home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-05-16 | 107.8 KB | 3,208 lines |
- // copyright 1993 Michael B. Johnson; some portions copyright 1994, MIT
- // see COPYRIGHT for reuse legalities
- //
-
- /* Copyright 1993 Michael B. Johnson
- * Permission to use, copy, modify, and distribute this
- * software and its documentation for any non-commercial
- * purpose and without fee is hereby granted, provided that the
- * above copyright notice appears in all copies. Michael B. Johnson
- * makes no representations about the suitability of this
- * software for any purpose. It is provided "as is" without
- * express or implied warranty.
- *
- * Permission to use, copy, modify or distribute this software
- * and its documentation for any commercial purpose must be
- * confirmed in writing with Michael B. Johnson. He can be
- * contacted at:
- * 20 Ames St. E15-023G
- * Cambridge, MA 02141
- * (617) 547 0563
- *
- */
- #import "WW3DWell.h"
-
- #import "WWTCLKit.h"
-
- #import "WW3DCamera.h"
- #import "WW3DShader.h"
- #import "WW3DShape.h"
- #import "WW3DShapeBrowser.h"
- #import "WWEveParser.h"
- #import "WWShaderArgPointMatrix.h"
- #import "WWShaderArgColorWell.h"
- #import "WWShaderArgTextField.h"
- #import "WWDADLightView.h"
-
- #import "EveCommand.h"
- #import "WWSceneClock.h"
-
- #import "aspectRatios.h"
-
- #import "WWRenderWrangler.h"
-
- #import <apps/InterfaceBuilder.h>
-
-
- @implementation WW3DWell
-
- #define BEZEL_X 7
- #define BEZEL_Y 7
-
- #define WELL_X (BEZEL_X + 2)
- #define WELL_Y (BEZEL_Y + 2)
-
-
- + initialize { return [WW3DWell setVersion:5], self; }
-
-
- /*
- ==========================================================================
- subext() -- Remove extension from fname only if it is there.
-
- ==========================================================================
- */
- static char
- *subext(fname, ext)
- register char *fname, *ext;
- {
- int fl, el;
-
- for ( fl = strlen(fname), el = strlen(ext);
- --el > -1 && --fl > -1 && fname[fl] == ext[el]; )
- ;
- if (el == -1)
- { fname[fl] = '\0';
- }
- return(fname);
- }
-
-
- /*
- ==========================================================================
- basename() -- deletes any prefix ending in `/' and the suffix.
-
- ==========================================================================
- */
- static char
- *basename(str, sfx, dest)
- char *str, *sfx, *dest;
- {
- char temp[1024];
- char *p, *p1;
- char *subext();
-
- p = p1 = temp;
- strcpy(p, str);
- while (*p)
- { if (*p++ == '/')
- { p1 = p;
- }
- }
- strcpy (dest, subext(p1, sfx));
- return(dest);
- }
-
-
- - initFrame:(const NXRect *)r
- {
- int width, height;
- //NXRect newR;
- const char *WDRAG_PBTYPE[] = { NXFilenamePboardType, NULL};
-
-
- selectedColor = NXConvertRGBToColor(0.9, 0.9, 0.0);
- unselectedColor = NXConvertRGBToColor(0.9, 0.9, 0.9);
-
- replyTextColor = NXConvertRGBToColor(0.9, 0.0, 0.0);
- sendTextColor = NXConvertRGBToColor(0.0, 0.0, 0.9);
-
- edgeClicked = NO;
-
- aspectRatioType = WW_ASPECT_DONT_CARE;
- width = r->size.width;
- height = r->size.height;
- aspectRatio = width/height;
-
- //newR.origin.x = r->origin.x;
- //newR.origin.y = r->origin.y;
- //newR.size.width = newR.size.height = width;
- //[super initFrame:&newR];
-
- [super initFrame:r];
- [self registerForDraggedTypes:WDRAG_PBTYPE count:1];
-
- if ([NXApp respondsTo:@selector(isTestingInterface)]) // we're in IB
- { [window setDepthLimit:NX_TwelveBitRGBDepth];
- }
-
- bezelRect.origin.x = BEZEL_X;
- bezelRect.origin.y = BEZEL_Y;
- bezelRect.size.width = width - (2 * BEZEL_X);
- bezelRect.size.height = height - (2 * BEZEL_Y);
-
- wellRect.origin.x = WELL_X;
- wellRect.origin.y = WELL_Y;
- wellRect.size.width = width - (2 * WELL_X);
- wellRect.size.height = height - (2 * WELL_Y);
-
- // A WW3DWell has a notion of a current scene, which is going on inside of it.
- // The scene can be being built, or being replayed, or even being edited.
- // when the scene is being built or edited, the WW3DWell's sceneClock provides
- // information of where in the scene we are. When the scene is being played
- // back, the WW3DWell's camera is responsible for providing information about
- // where in the scene we are. One important difference is that when we are
- // looking at the scene and the sceneClock is providing the time, it is an
- // exact value. When the scene is being played back, we can be at a region
- // of time, since the camera thinks of time as a series of frames, and a
- // frame can last for some amount of time (hence things can get motion blurred).
-
- // In the default, we assume that things are being simulated at a rate of 60Hz,
- // and then the default camera runs at about 15 fps, and that a given scene
- // starts at 0 and is only 10 seconds long. For the average motion test, this
- // is fine, and if you need more, well, change it...
- sceneClock = [[WWSceneClock alloc] init];
-
- camera = [[WW3DCamera alloc] initFrame:&wellRect];
- [camera setAutosizing:(NX_WIDTHSIZABLE | NX_HEIGHTSIZABLE)];
- [camera setDelegate:self];
- [camera setSceneClock:sceneClock];
-
- // this tickles a bug in the 3.2 release for HP; don't do it
- //imageView = camera;
- imageView = nil;
- reuseImageView = YES;
- useRendribInstead = NO;
- beepWhenDone = YES;
-
- projectionType = N3D_Perspective;
- [camera setProjection:projectionType];
-
- // stuff for RIBParser
- ribParser = [[WWEveParser alloc] init];
- [ribParser setSceneClock:sceneClock];
- [camera setRunTimeSystem:ribParser];
-
- // oh boy, is this a hack...
- [ribParser setViewToUpdate:camera];
- [ribParser setWell:self];
-
- // just so everything's in synch to start...
- [ribParser setRootShape:[camera worldShape]];
-
- [self setAutoresizeSubviews:YES];
- if (![self addSubview:camera])
- { return nil;
- }
-
- wellControlPanel = nil;
- statusBufSize = 2048;
- statusBuf = (char *)NXZoneCalloc([self zone], statusBufSize, sizeof(char));
-
- // need to make sure ribParser is initialized before I do this!!!
- [sceneClock setScene:ribParser];
- [sceneClock setDelegate:self];
- [sceneClock setSamplesPerSecond:60]; // do this after setting the scene!
-
- imageViewWindowList = [[List alloc] init];
-
- return self;
- }
-
- - awake
- {
- const char *WDRAG_PBTYPE[] = { NXFilenamePboardType, NULL};
-
-
- [super awake];
-
- [self registerForDraggedTypes:WDRAG_PBTYPE count:1];
- [camera sizeTo:wellRect.size.width :wellRect.size.height];
- [camera setDelegate:self];
-
- projectionType = N3D_Perspective;
- [camera setProjection:projectionType];
- replyTextColor = NXConvertRGBToColor(0.9, 0.0, 0.0);
- sendTextColor = NXConvertRGBToColor(0.0, 0.0, 0.9);
- edgeClicked = NO;
-
- // stuff for RIBParser
- ribParser = [[WWEveParser alloc] init];
- [ribParser setSceneClock:sceneClock];
- [camera setRunTimeSystem:ribParser];
-
- // oh boy, is this a hack...
- [ribParser setViewToUpdate:camera];
- [ribParser setWell:self];
-
- // just so everything's in synch to start...
- [ribParser setRootShape:[camera worldShape]];
-
- // these should be archived, really...
- selectedColor = NXConvertRGBToColor(0.9, 0.9, 0.0);
- unselectedColor = NXConvertRGBToColor(0.9, 0.9, 0.9);
-
- wellControlPanel = nil;
-
- statusBufSize = 2048;
- statusBuf = (char *)NXZoneCalloc([self zone], statusBufSize, sizeof(char));
-
- // need to make sure ribParser is initialized before I do this!!!
- [sceneClock setScene:ribParser];
- [sceneClock setDelegate:self];
- [sceneClock setSamplesPerSecond:60]; // do this after setting the scene!
-
- imageViewWindowList = [[List alloc] init];
-
- // nil the (potentially) archived
- if (imageView == camera)
- { NXLogError("warning: setting imageView to nil to avoid tickling NeXT's 3.2 bug...\n");
- imageView = nil;
- }
-
- // in case we have an old camera; we need to reset our sceneClock as the sceneClock
- [camera setSceneClock:sceneClock];
-
- return self;
- }
-
- - free
- {
- char tmpFilename[64];
- int i, howMany = [imageViewWindowList count];
- id aWindow;
-
-
- [statusText setStringValue:"freeing WW3DWell..."]; [statusText display]; NXPing();
- [self unregisterDraggedTypes];
-
- for (i = 0; i < howMany; i++)
- { aWindow = [imageViewWindowList objectAt:i];
- [aWindow setFreeWhenClosed:NO];
- [aWindow close];
- [aWindow free]; // that should automatically free the movie view
- }
- [imageViewWindowList free];
-
- // we want to free parser, because we want the ribParser, which
- // might have traces set up in the rootShape of the camera to be able to
- // untrace themselves cleanly...
- [ribParser free];
- // need to make sure the camera doesn't try to free its worldShape, since
- // the ribParser just free'ed it
- [camera setWorldShape:nil];
- [camera setNoCurrentShape:nil];
- [camera removeFromSuperview];
- [camera free];
-
- // in order for the following to do the right thing, the
- // wellControlPanel has to *not* free itself when closed.
- // to make sure of this, we'll send it a don't free on
- // close message right before we close it...
- [statusText setStringValue:"bye!"]; [statusText display]; NXPing();
- if (statusBuf) { NXZoneFree([self zone], statusBuf); }
-
- [sceneClockControlPanel setFreeWhenClosed:NO];
- [sceneClockControlPanel close];
- [sceneClockControlPanel free];
-
- [wellControlPanel setFreeWhenClosed:NO];
- [wellControlPanel close];
-
- // note that by free'ing the wellControlPanel, it should automatically
- // free any panels it might have open, like the shape panel...
- [wellControlPanel free];
-
- // blow away any tmp files I made...
- sprintf(tmpFilename, "/tmp/foo%d.rib", getpid());
- unlink(tmpFilename);
- sprintf(tmpFilename, "/tmp/foo%d.tiff", getpid());
- unlink(tmpFilename);
-
- return [super free];
- }
-
- - reinitializeStuffFromZone:(NXZone *)zone
- {
- return self;
- }
-
- - copyFromZone:(NXZone *)zone
- {
- id newCopy = [super copyFromZone:zone];
-
- [newCopy reinitializeStuffFromZone:zone];
-
- return newCopy;
- }
-
- #define EPSILON 10
-
- - sizeTo:(NXCoord)width :(NXCoord)height
- {
- sprintf(statusBuf, "resizing to (%f, %f)...", width, height);
- [statusText setStringValue:statusBuf]; [statusText display]; NXPing();
- // don't want to make it too small...
- if (width < ((2 * BEZEL_X) + EPSILON)) return nil;
- if (height < ((2 * BEZEL_Y) + EPSILON)) return nil;
-
-
- // let's say it comes in at 100, 100 and you're supposed to be constrained to 4:3
- // you don't want it to get bigger than 100, 100, so... you frob the width, not the height
- switch (aspectRatioType)
- { case WW_ASPECT_DONT_CARE:
- aspectRatio = width/height;
- [self revertControlPanel];
- break;
- case WW_ASPECT_NTSC: // 1.33:1
- height = width/1.33;
- aspectRatio = 1.33;
- break;
- case WW_ASPECT_AMERICAN_WIDESCREEN: // 1.85:1
- //width = height * 1.85;
- height = width/1.85;
- aspectRatio = 1.85;
- break;
- case WW_ASPECT_EUROPEAN_WIDESCREEN: // 1.66:1
- //width = height * 1.66;
- height = width/1.66;
- aspectRatio = 1.66;
- break;
- case WW_ASPECT_VISTA_VISION: // 2.21:1
- //width = height * 1.21;
- height = width/2.21;
- aspectRatio = 2.21;
- break;
- case WW_ASPECT_SQUARE: // 1:1
- if (width < height)
- { height = width;
- }
- else
- { width = height;
- }
- aspectRatio = 1.0;
- break;
- case WW_ASPECT_CUSTOM: //aspectX:aspectY
- if (aspectRatio < 1.0)
- { width = height * aspectRatio;
- }
- else
- { height = width/aspectRatio;
- }
- break;
- default:
- NXLogError("unknown aspect ratio type: %d", aspectRatioType);
- break;
- }
-
- bezelRect.size.width = width - (2 * BEZEL_X);
- bezelRect.size.height = height - (2 * BEZEL_Y);
-
- wellRect.size.width = width - (2 * WELL_X);
- wellRect.size.height = height - (2 * WELL_Y);
-
- [super sizeTo:width :height];
-
- [camera sizeTo:wellRect.size.width :wellRect.size.height];
- [window display];
- sprintf(statusBuf, "resized to (%f, %f)", (width - 18), (height - 18));
- [statusText setStringValue:statusBuf]; [statusText display]; NXPing();
-
- return self;
- }
-
- // window delegate method to resize to right aspect ratio this should
- // be used when the rib well is the only view inside a window - Make the
- // rib well the delegate of the window and "you're all set..."
- - windowWillResize:sender toSize:(NXSize *)frameSize
- {
- switch (aspectRatioType)
- { case WW_ASPECT_DONT_CARE:
- break;
- case WW_ASPECT_NTSC: // 1.33:1
- frameSize->height = frameSize->width/1.33;
- break;
- case WW_ASPECT_AMERICAN_WIDESCREEN: // 1.85:1
- frameSize->height = frameSize->width/1.85;
- break;
- case WW_ASPECT_EUROPEAN_WIDESCREEN: // 1.66:1
- frameSize->height = frameSize->width/1.66;
- break;
- case WW_ASPECT_VISTA_VISION: // 2.21:1
- frameSize->height = frameSize->width/2.21;
- break;
- case WW_ASPECT_SQUARE: // 1:1
- if (frameSize->width < frameSize->height)
- { frameSize->height = frameSize->width;
- }
- else
- { frameSize->width = frameSize->height;
- }
- break;
- case WW_ASPECT_CUSTOM: //aspectX:aspectY
- if (aspectRatio < 1.0)
- { frameSize->width = frameSize->height * aspectRatio;
- }
- else
- { frameSize->height = frameSize->width/aspectRatio;
- }
- break;
- default:
- NXLogError("unknown aspect ratio type: %d - unable to change window size...", aspectRatioType);
- break;
- }
- sprintf(statusBuf, "constrained window resizing to (%f, %f)...", frameSize->width, frameSize->height);
- [statusText setStringValue:statusBuf]; [statusText display]; NXPing();
-
- return self;
- }
-
-
- - empty:sender
- {
- // tell the camera it's worldShape is nil
- [camera setWorldShape:nil];
-
- // tell the parser it's rootShape is nil
- // it's smart enough to free the old one
- [ribParser setRootShape:nil];
- return self;
- }
-
- - revertShapeInspectorFor:newShape
- {
- RtMatrix anRtMatrix;
- RtBound boundingBox;
-
-
- // shape stuff
- [self revertSurfaceShaderInspectorFor:[newShape shaderType:SLO_TYPE_SURFACE]];
- [self revertDisplacementShaderInspectorFor:[newShape shaderType:SLO_TYPE_DISPLACEMENT]];
-
- [(WW3DShape *)newShape getBoundingBox:&boundingBox];
- [[boundingBoxMatrix cellAt:0 :0] setFloatValue:boundingBox[0]];
- [[boundingBoxMatrix cellAt:1 :0] setFloatValue:boundingBox[1]];
- [[boundingBoxMatrix cellAt:0 :1] setFloatValue:boundingBox[2]];
- [[boundingBoxMatrix cellAt:1 :1] setFloatValue:boundingBox[3]];
- [[boundingBoxMatrix cellAt:0 :2] setFloatValue:boundingBox[4]];
- [[boundingBoxMatrix cellAt:1 :2] setFloatValue:boundingBox[5]];
- [newShape getTransformMatrix:anRtMatrix];
- [self drawRtMatrix:anRtMatrix inMatrix:transformMatrix];
-
- [self fillRIBCommandsMatrix:ribCommandsMatrix];
-
- [boundingBoxMatrix display];
- [transformMatrix display];
- [ribCommandsMatrix display];
-
- return self;
- }
-
- - enableCameraInspector
- {
- if (cameraInspectorInvalid)
- { [eyePointMatrix setEnabled:YES];
- [viewPointMatrix setEnabled:YES];
- [rollAngleText setEnabled:YES];
- [cameraTransformMatrix setEnabled:YES];
-
- [focalLengthText setEnabled:YES];
- [focalDistanceText setEnabled:YES];
- [fStopText setEnabled:YES];
- [exposureLengthText setEnabled:YES];
-
- cameraInspectorInvalid = NO;
- }
-
- return self;
- }
-
- - invalidateCameraInspector
- {
- if (!cameraInspectorInvalid)
- { [eyePointMatrix setEnabled:NO];
- [viewPointMatrix setEnabled:NO];
- [rollAngleText setEnabled:NO];
- [cameraTransformMatrix setEnabled:NO];
-
- [focalLengthText setEnabled:NO];
- [focalDistanceText setEnabled:NO];
- [fStopText setEnabled:NO];
- [exposureLengthText setEnabled:NO];
-
- // force redisplay
- [eyePointMatrix display];
- [viewPointMatrix display];
- [cameraTransformMatrix display];
-
- cameraInspectorInvalid = YES;
- }
-
- return self;
- }
-
- - revertCameraInspector
- {
- RtMatrix anRtMatrix;
- RtPoint anEyePoint, aViewPoint;
- RtFloat aRollAngle;
- float elf;
-
- [self enableCameraInspector];
-
- [camera getEyeAt:&anEyePoint toward:&aViewPoint roll:&aRollAngle];
- [[eyePointMatrix cellAt:0 :0] setFloatValue:anEyePoint[0]];
- [[eyePointMatrix cellAt:0 :1] setFloatValue:anEyePoint[1]];
- [[eyePointMatrix cellAt:0 :2] setFloatValue:anEyePoint[2]];
- [[viewPointMatrix cellAt:0 :0] setFloatValue:aViewPoint[0]];
- [[viewPointMatrix cellAt:0 :1] setFloatValue:aViewPoint[1]];
- [[viewPointMatrix cellAt:0 :2] setFloatValue:aViewPoint[2]];
- [rollAngleText setFloatValue:aRollAngle];
-
-
- [camera getTransformMatrix:anRtMatrix];
- [self drawRtMatrix:anRtMatrix inMatrix:cameraTransformMatrix];
-
- [focalLengthText setFloatValue:[camera focalLength]];
- [focalDistanceText setFloatValue:[camera focalDistance]];
- [fStopText setFloatValue:[camera fStop]];
- [exposureLengthText setFloatValue:[camera exposureLength]];
-
- // WAVE: need to deal with shotOutputTypeMatrix here...
-
- [totalFrameCountText setIntValue:([camera endFrame] - [camera startFrame])];
- [framesPerSecondText setFloatValue:[camera framesPerSecond]];
- [shotLengthText setFloatValue:[camera shotLength]];
- [frameNumberText setFloatValue:[camera frameNumber]];
-
- [shotStartTimeText setFloatValue:[camera shotStartTime]];
- elf = [camera exposureLengthFactor];
- [exposureLengthSlider setFloatValue:elf];
- [exposureLengthPercentageText setFloatValue:(100. * elf)];
- if (elf == 0.0)
- { [exposureLengthStrobeSwitch setIntValue:1];
- [exposureLengthFilmSwitch setIntValue:0];
- [exposureLengthVideoSwitch setIntValue:0];
- }
- else
- { if (elf == 0.5)
- { [exposureLengthStrobeSwitch setIntValue:0];
- [exposureLengthFilmSwitch setIntValue:1];
- [exposureLengthVideoSwitch setIntValue:0];
- }
- else
- { if (elf == 1.0)
- { [exposureLengthStrobeSwitch setIntValue:0];
- [exposureLengthFilmSwitch setIntValue:0];
- [exposureLengthVideoSwitch setIntValue:1];
- }
- else
- { [exposureLengthStrobeSwitch setIntValue:0];
- [exposureLengthFilmSwitch setIntValue:0];
- [exposureLengthVideoSwitch setIntValue:0];
- }
- }
- }
-
- [binaryRIBSwitch setState:[camera binaryRIB]];
- [reuseImageViewSwitch setState:reuseImageView];
- [useRendribInsteadSwitch setState:[self useRendribInstead]];
- [beepWhenDoneSwitch setState:beepWhenDone];
-
- // force redisplay
- [eyePointMatrix display];
- [viewPointMatrix display];
- [cameraTransformMatrix display];
-
- cameraInspectorInvalid = YES;
-
- return self;
- }
-
- - imageView { return imageView; }
-
- - setCurrentShape:newShape
- {
- [camera setCurrentShape:newShape];
- [delegate wellWasUpdated:camera];
- [[shapeBrowser loadColumnZero] selectRootShape];
- return self;
- }
-
- - setWorldShape:aShape
- {
- [camera setWorldShape:aShape];
- [camera setNoCurrentShape:nil];
- [camera setCurrentShape:[camera worldShape]]; // set current shape to be top
- [delegate wellWasUpdated:camera];
- [[shapeBrowser loadColumnZero] selectRootShape];
- return self;
- }
-
-
- - buildNewShapeHierarchyFromRIBFile:(const char *)filename
- {
- id aShape;
-
-
- sprintf(statusBuf, "building new shape hierarchy from rib file %s...", filename);
- [statusText setStringValue:statusBuf]; [statusText display]; NXPing();
- if (filename && *filename)
- { // reset the sceneClock to the start of a new scene; really should probably make sure I can unwind this...
- [sceneClock reset:nil];
- aShape = [ribParser buildNewShapeHierarchyFromRIBFile:filename];
- if (!aShape)
- { NXLogError("unable to build shape hierarchy from RIB file <%s>\n", filename);
- return nil;
- }
- [self setWorldShape:aShape];
- }
- [statusText setStringValue:"done"]; [statusText display]; NXPing();
- [statusText setStringValue:"calculating bounding boxes..."]; [statusText display]; NXPing();
- [[camera worldShape] calculateBoundingBoxStartingAt:[sceneClock timestamp] endingAt:[sceneClock timestamp]];
- [statusText setStringValue:"done"]; [statusText display]; NXPing();
- [camera display];
- return self;
- }
-
- - addToShapeHierarchyFromRIBFile:(const char *)filename
- {
- id aShape;
-
-
- sprintf(statusBuf, "adding new shape hierarchy from rib file %s...", filename);
- [statusText setStringValue:statusBuf]; [statusText display]; NXPing();
- if (filename && *filename)
- { [ribParser setRootShapeInUse:YES];
- aShape = [ribParser buildNewShapeHierarchyFromRIBFile:filename :NO];
- if (!aShape)
- { NXLogError("unable to build shape hierarchy from RIB file <%s>\n", filename);
- [ribParser setRootShapeInUse:NO];
- return nil;
- }
- [[camera currentShape] addChild:aShape]; // don't free the old one cause it might be shared - need a way to track this...
- [self setCurrentShape:aShape];
- }
- [statusText setStringValue:"done"]; [statusText display]; NXPing();
- [statusText setStringValue:"calculating bounding boxes..."]; [statusText display]; NXPing();
- [[camera worldShape] calculateBoundingBoxStartingAt:[sceneClock timestamp] endingAt:[sceneClock timestamp]];
- [statusText setStringValue:"done"]; [statusText display]; NXPing();
- [camera display];
- return self;
- }
-
- - buildNewShapeHierarchyFromEveFile:(const char *)filename
- {
- id aShape;
-
-
- sprintf(statusBuf, "building new shape hierarchy from eve file %s...", filename);
- [statusText setStringValue:statusBuf]; [statusText display]; NXPing();
- if (filename && *filename)
- { // reset the sceneClock to the start of a new scene; really should probably make sure I can unwind this...
- [sceneClock reset:nil];
- [camera setWorldShape :nil];
- [camera setNoCurrentShape:nil];
- aShape = [ribParser buildNewShapeHierarchyFromEveFile:filename];
- if (!aShape)
- { NXLogError("unable to build shape hierarchy from Eve file <%s>\n", filename);
- return nil;
- }
- [self setWorldShape:aShape];
- }
- [statusText setStringValue:"done"]; [statusText display]; NXPing();
- [statusText setStringValue:"calculating bounding boxes..."]; [statusText display]; NXPing();
- [[camera worldShape] calculateBoundingBoxStartingAt:[sceneClock timestamp] endingAt:[sceneClock timestamp]];
- [statusText setStringValue:"done"]; [statusText display]; NXPing();
- [camera display];
- return self;
- }
-
- - readMdlTemplateFile:(const char *)filename
- {
- static char thePath[MAXPATHLEN+1];
-
-
- sprintf(statusBuf, "reading model template file %s...", filename);
- [statusText setStringValue:statusBuf]; [statusText display]; NXPing();
- if (filename && *filename)
- { // set the modelPath tcl variable to be the path of the .mdl file,
- // and then tell the tcl interp to parse the file
- [[ribParser tclInterp] setVar:"modelPath" toValue:(char *)filename];
- sprintf(thePath, "%s/model.eve", filename);
- [self evaluateEveFile:thePath];
- }
- [statusText setStringValue:"done"]; [statusText display]; NXPing();
- return self;
- }
-
- - buildNewShapeHierarchyFromMdlFile:(const char *)filename
- {
- char thePath[MAXPATHLEN+1];
-
-
- sprintf(statusBuf, "building new shape hierarchy from model file package %s...", filename);
- [statusText setStringValue:statusBuf]; [statusText display]; NXPing();
- if (filename && *filename)
- { // reset the sceneClock to the start of a new scene; really should probably make sure I can unwind this...
- [sceneClock reset:nil];
- // set the modelPath tcl variable to be the path of the .mdl file,
- // and then tell the tcl interp to parse the file
- [[ribParser tclInterp] setVar:"modelPath" toValue:(char *)filename];
- sprintf(thePath, "%s/model.eve", filename);
- [self buildNewShapeHierarchyFromEveFile:thePath];
- }
- [statusText setStringValue:"done"]; [statusText display]; NXPing();
- [statusText setStringValue:"calculating bounding boxes..."]; [statusText display]; NXPing();
- [[camera worldShape] calculateBoundingBoxStartingAt:[sceneClock timestamp] endingAt:[sceneClock timestamp]];
- [statusText setStringValue:"done"]; [statusText display]; NXPing();
- return self;
- }
-
- - addToShapeHierarchyFromMdlFile:(const char *)filename
- {
- char thePath[MAXPATHLEN+1];
-
-
- sprintf(statusBuf, "adding new shape hierarchy from model file package %s...", filename);
- [statusText setStringValue:statusBuf]; [statusText display]; NXPing();
- if (filename && *filename)
- { // set the modelPath tcl variable to be the path of the .mdl file,
- // and then tell the tcl interp to parse the file
- [[ribParser tclInterp] setVar:"modelPath" toValue:(char *)filename];
- sprintf(thePath, "%s/model.eve", filename);
- [self addToShapeHierarchyFromEveFile:thePath];
- }
- [statusText setStringValue:"done"]; [statusText display]; NXPing();
- [statusText setStringValue:"calculating bounding boxes..."]; [statusText display]; NXPing();
- [[camera worldShape] calculateBoundingBoxStartingAt:[sceneClock timestamp] endingAt:[sceneClock timestamp]];
- [statusText setStringValue:"done"]; [statusText display]; NXPing();
- return self;
- }
-
-
- - buildNewShapeHierarchyFromSceneFile:(const char *)filename
- {
- id aShape;
-
-
- sprintf(statusBuf, "building new shape hierarchy from scene file %s...", filename);
- [statusText setStringValue:statusBuf]; [statusText display]; NXPing();
- if (filename && *filename)
- { // reset the sceneClock to the start of a new scene; really should probably make sure I can unwind this...
- [sceneClock reset:nil];
- [camera setWorldShape :nil];
- [camera setNoCurrentShape:nil];
- [ribParser setFrozen:YES];
- aShape = [ribParser buildNewShapeHierarchyFromEveFile:filename];
- [ribParser setFrozen:NO];
- if (!aShape)
- { NXLogError("unable to build shape hierarchy from Eve file <%s>\n", filename);
- return nil;
- }
- [self setWorldShape:aShape];
- }
- [statusText setStringValue:"done"]; [statusText display]; NXPing();
- [statusText setStringValue:"calculating bounding boxes..."]; [statusText display]; NXPing();
- [[camera worldShape] calculateBoundingBoxStartingAt:[sceneClock timestamp] endingAt:[sceneClock timestamp]];
- [statusText setStringValue:"done"]; [statusText display]; NXPing();
- [camera display];
- return self;
- }
-
- - addToShapeHierarchyFromSceneFile:(const char *)filename
- {
- id aShape;
-
-
- sprintf(statusBuf, "adding new shape hierarchy from eve file %s...", filename);
- [statusText setStringValue:statusBuf]; [statusText display]; NXPing();
- if (filename && *filename)
- { // tell the rib parser not to blow away it's old root shape
- [ribParser setFrozen:YES];
- [ribParser setRootShapeInUse:YES];
- aShape = [ribParser buildNewShapeHierarchyFromEveFile:filename :NO];
- [ribParser setFrozen:NO];
- if (!aShape)
- { NXLogError("unable to build shape hierarchy from EVE file <%s>\n", filename);
- [ribParser setRootShapeInUse:NO];
- return nil;
- }
- [[camera currentShape] addChild:aShape]; // don't free the old one cause it might be shared - need a way to track this...
- [self setCurrentShape:aShape];
- }
- [statusText setStringValue:"done"]; [statusText display]; NXPing();
- [statusText setStringValue:"calculating bounding boxes..."]; [statusText display]; NXPing();
- [[camera worldShape] calculateBoundingBoxStartingAt:[sceneClock timestamp] endingAt:[sceneClock timestamp]];
- [statusText setStringValue:"done"]; [statusText display]; NXPing();
- [camera display];
- return self;
- }
-
-
- - addToShapeHierarchyFromEveFile:(const char *)filename
- {
- id aShape;
-
-
- sprintf(statusBuf, "adding new shape hierarchy from eve file %s...", filename);
- [statusText setStringValue:statusBuf]; [statusText display]; NXPing();
- if (filename && *filename)
- { // tell the rib parser not to blow away it's old root shape
- [ribParser setRootShapeInUse:YES];
- aShape = [ribParser buildNewShapeHierarchyFromEveFile:filename :NO];
- if (!aShape)
- { NXLogError("unable to build shape hierarchy from EVE file <%s>\n", filename);
- [ribParser setRootShapeInUse:NO];
- return nil;
- }
- [[camera currentShape] addChild:aShape]; // don't free the old one cause it might be shared - need a way to track this...
- [self setCurrentShape:aShape];
- }
- [statusText setStringValue:"done"]; [statusText display]; NXPing();
- [statusText setStringValue:"calculating bounding boxes..."]; [statusText display]; NXPing();
- [[camera worldShape] calculateBoundingBoxStartingAt:[sceneClock timestamp] endingAt:[sceneClock timestamp]];
- [statusText setStringValue:"done"]; [statusText display]; NXPing();
- [camera display];
- return self;
- }
-
- - evaluateEveFile:(const char *)filename
- {
- if (filename && *filename)
- { if ([ribParser evaluateEveFile:filename])
- { return self;
- }
- }
- return nil;
- }
-
-
- - turnOffCropWindow { [camera turnOffCropWindow]; return self; }
-
-
- - shape { return [camera worldShape]; }
- - parser { return ribParser; }
- - camera { return camera; }
-
- - drawSelf:(const NXRect *)r :(int)n
- {
- NXDrawButton(r, r);
- if (edgeClicked)
- { PSsetgray(NX_WHITE);
- PSrectfill((r->origin.x + 1), (r->origin.y + 1), (r->size.width - 2), (r->size.height - 2));
- }
- NXDrawGrayBezel(&bezelRect, &bezelRect);
-
- return self;
- }
-
- - windowWillClose:sender
- {
- int i = 0,
- howMany = [imageViewWindowList count];
- BOOL done = NO;
-
-
- if (wellControlPanel && (sender == wellControlPanel))
- { edgeClicked = NO;
- wellControlPanel = nil;
- [self display];
- return self;
- }
-
-
- // if it's one of the imageViewWindows, delete it from the list...
- while (!done && (i < howMany))
- { if (sender == [imageViewWindowList objectAt:i])
- { [imageViewWindowList removeObjectAt:i];
- done = YES;
- }
- i++;
- }
- // if it's the current imageViewWindow, nil out it and it's view
- if (sender == imageViewWindow)
- { imageView = nil;
- imageViewWindow = nil;
- }
- return self;
- }
-
- - revertSceneClockInspector
- {
- [sceneClockSamplesPerSecondText setFloatValue:[sceneClock samplesPerSecond]];
- [sceneClockTimeText setFloatValue:[sceneClock timestamp]];
- [sceneClockIncrementText setFloatValue:[sceneClock increment]];
- [sceneClockSkipText setFloatValue:[sceneClock skip]];
- [sceneClockRatioText setFloatValue:[sceneClock ratio]];
-
- if ([sceneClock isPaused])
- { [sceneClockButtonMatrix selectCellWithTag:2]; // really should #define this somewhere, doofus
- }
-
- [sceneClockMarkText setFloatValue:[sceneClock mark]];
-
- // is this the best place to do this?
- [self synchCameraToSceneClock];
-
- return self;
- }
-
- - revertControlPanel
- {
- if (!wellControlPanel) // this should speed stuff up a lot when the panel's not around...
- { return self;
- }
-
- [statusText setStringValue:"reverting control panel..."]; [statusText display]; NXPing();
-
- // note that I'm leaking here...
- [shapeBrowser setPath:[[camera currentShape] getPath]];
-
- [ignoreShadingRateSwitch setState:[ribParser ignoreShadingRate]];
- [ignoreColorsSwitch setState:[ribParser ignoreColors]];
- [ignoreLightsSwitch setState:[ribParser ignoreLights]];
- [ignoreShadersSwitch setState:[ribParser ignoreShaders]];
- [firmTransformsSwitch setState:[ribParser firmTransforms]];
- [treatAttributeBeginLikeStartShapeSwitch setState:[ribParser treatAttributeBeginLikeStartShape]];
- [treatTransformBeginLikeAttributeBeginSwitch setState:[ribParser treatTransformBeginLikeAttributeBegin]];
- [applyShadersDirectlyToCurrentShapeSwitch setState:[ribParser applyShadersDirectlyToCurrentShape]];
- [lowRezTesselationText setFloatValue:[camera lowRezTesselation]];
- [tesselationText setFloatValue:[camera tesselation]];
- [projectionTypeMatrix selectCellWithTag:projectionType];
- [selectedColorWell setColor:selectedColor];
- [unselectedColorWell setColor:unselectedColor];
- [shadingRateText setFloatValue:[camera shadingRate]];
- [shadingRateSlider setFloatValue:[camera shadingRate]];
- [binaryRIBSwitch setState:[camera binaryRIB]];
- if ([self useRendribInstead])
- { [shadingRateText setEnabled:NO];
- [shadingRateSlider setEnabled:NO];
- }
- else
- { [shadingRateText setEnabled:YES];
- [shadingRateSlider setEnabled:YES];
- }
-
- [aspectRatioMatrix selectCellWithTag:aspectRatioType];
- [customAspectRatioText setFloatValue:aspectRatio];
- [customAspectRatioText setEnabled:(aspectRatioType == WW_ASPECT_CUSTOM)];
- [fovText setFloatValue:[camera fieldOfView]];
- [fovSlider setFloatValue:[camera fieldOfView]];
- [trackballAffectsMatrix selectCellWithTag:[camera trackballAffects]];
- [trackballXYZMatrix selectCellWithTag:[camera trackballXYZ]];
-
- [renderWorldAsBoxSwitch setState:[camera renderWorldAsBox]];
- [renderCurrentAsBoxSwitch setState:[camera renderCurrentAsBox]];
- [worldIsVisibleSwitch setState:[camera worldIsVisible]];
- [currentIsVisibleSwitch setState:[camera currentIsVisible]];
-
- [backgroundColorWell setColor:[camera backgroundColor]];
-
- [showSelectedShapeSwitch setState:[camera showSelectedShape]];
- [drawOriginForSelectedShapeSwitch setState:[camera drawOriginForSelectedShape]];
- [renderStyleMatrix selectCellWithTag:[camera renderStyle]];
- [movingRenderStyleMatrix selectCellWithTag:[camera movingRenderStyle]];
-
- // shape stuff
- [self revertShapeInspectorFor:[camera currentShape]];
-
- // camera stuff
- [self revertCameraInspector];
-
- // scene stuff
- [self revertSceneClockInspector];
- [statusText setStringValue:"done"]; [statusText display]; NXPing();
- return self;
- }
-
- - takeShowSelectedShape:sender
- { [camera setShowSelectedShape:[sender intValue]];
- [self revertControlPanel];
- [delegate sceneWasUpdated:camera];
- [self display];
- return self;
- }
-
- - takeDrawOriginForSelectedShape:sender
- { [camera setDrawOriginForSelectedShape:[sender intValue]];
- [self revertControlPanel];
- [delegate sceneWasUpdated:camera];
- [self display];
- return self;
- }
-
- - takeRenderStyleFromMatrix:sender
- { [camera setRenderStyle:[[sender selectedCell] tag]];
- [self revertControlPanel];
- return self;
- }
-
- - takeMovingRenderStyleFromMatrix:sender
- { [camera setMovingRenderStyle:[[sender selectedCell] tag]];
- [self revertControlPanel];
- return self;
- }
-
- - loadImageView
- { id bundle = [NXBundle bundleForClass: [self class]];
- char path[MAXPATHLEN + 1];
-
- if (!bundle)
- { NXLogError("No bundle for Class %s - unable to loadImageView\n", [self name]);
- return nil;
- }
- if (![bundle getPath:path forResource:"WW3DWellImageView" ofType:"nib"])
- { NXLogError("No path for WW3DWellImageView.nib.\n");
- return nil;
- }
- [NXApp loadNibFile:path owner:self withNames:NO fromZone:[self zone]];
- //NXLogError ("Loaded %s.\n", path);
- [imageViewWindowList addObject:imageViewWindow];
- [imageView setImageIsShared:NO];
-
- return self;
- }
-
- - (BOOL)binaryRIB { return [camera binaryRIB]; }
- - setBinaryRIB:(BOOL)n { [camera setBinaryRIB:n]; return [self revertControlPanel]; }
- - takeBinaryRIB:sender { [camera takeBinaryRIB:sender]; return [self revertControlPanel]; }
-
- - (BOOL)reuseImageView { return reuseImageView; }
- - setReuseImageView:(BOOL)n { reuseImageView = n; return self; }
- - takeReuseImageView:sender { reuseImageView = [sender intValue]; return self; }
-
- - (BOOL)useRendribInstead { return [camera useRendribInstead]; }
- - setUseRendribInstead:(BOOL)n { [camera setUseRendribInstead:n]; return [self revertControlPanel]; }
- - takeUseRendribInstead:sender { [camera takeUseRendribInstead:sender]; return [self revertControlPanel]; }
-
- - (BOOL)beepWhenDone { return beepWhenDone; }
- - setBeepWhenDone:(BOOL)n { beepWhenDone = n; return self; }
- - takeBeepWhenDone:sender { beepWhenDone = [sender intValue]; return self; }
-
- - showImageView:sender
- {
- if (imageView && reuseImageView)
- { return self;
- }
- return [self loadImageView];
- }
-
-
- - showControlPanel:sender
- {
- NXRect scrollRect, contentRect, matrixRect;
-
-
-
- [[camera worldShape] setVisible:NO];
- // display myself so the fact that the edge is clicked is apparent...
- [self display]; NXPing();
-
- if (!wellControlPanel)
- { id bundle = [NXBundle bundleForClass: [self class]];
- char path[MAXPATHLEN + 1];
-
- if (!bundle)
- { NXLogError("No bundle for Class %s - unable to showControlPanel\n", [self name]);
- return nil;
- }
- if (![bundle getPath:path forResource:"WW3DWellControlPanel" ofType:"nib"])
- { NXLogError("No path for WW3DWellControlPanel.nib.\n");
- return nil;
- }
- [NXApp loadNibFile:path owner:self withNames:NO fromZone:[self zone]];
- //NXLogError ("Loaded %s.\n", path);
- //[self display]; NXPing();
-
- // free the extra windows we brought along
- [z_infoWindow setContentView:nil];
- [z_infoWindow free];
- [z_cameraWindow setContentView:nil];
- [z_cameraWindow free];
- [z_shapeWindow setContentView:nil];
- [z_shapeWindow free];
- [z_lightWindow setContentView:nil];
- [z_lightWindow free];
- [z_tclWindow setContentView:nil];
- [z_tclWindow free];
- [z_ribWindow setContentView:nil];
- [z_ribWindow free];
-
- // our surface shader matrix needs to be put into the lower left corner of the appropriate scrollView
-
- [suParmScrollView setBorderType:NX_BEZEL];
- [suParmScrollView setVertScrollerRequired:YES];
- [suParmScrollView setHorizScrollerRequired:NO];
- [suParmScrollView setAutoresizeSubviews:YES];
- [suParmScrollView getFrame:&scrollRect];
-
- // we need to set up the docView of the ClipView to contain both
- // the Matrix that we'll stick in plus the UI objects to manipulate
- // the args in the Matrix.
- [ScrollView getContentSize:&(contentRect.size) forFrameSize:&(scrollRect.size) horizScroller:NO vertScroller:YES borderType:NX_BEZEL];
- contentRect.origin.x = contentRect.origin.y = 0.0;
- [suParmScrollView setDocView:[[View alloc] initFrame:&contentRect]];
-
- // add the Matrix to the docView of the scrollView
- [suParmNameMatrix getFrame:&matrixRect];
- matrixRect.origin.x = matrixRect.origin.y = 0.0;
- [suParmNameMatrix setFrame:&matrixRect];
- [[suParmScrollView docView] addSubview:suParmNameMatrix];
-
- suArgViewList = [[List alloc] init];
-
- // our displacement shader matrix needs to be put into the lower left corner of the appropriate scrollView
- [diParmScrollView setBorderType:NX_BEZEL];
- [diParmScrollView setVertScrollerRequired:YES];
- [diParmScrollView setHorizScrollerRequired:NO];
- [diParmScrollView setAutoresizeSubviews:YES];
- [diParmScrollView getFrame:&scrollRect];
-
- // we need to set up the docView of the ClipView to contain both
- // the Matrix that we'll stick in plus the UI objects to manipulate
- // the args in the Matrix.
- [ScrollView getContentSize:&(contentRect.size) forFrameSize:&(scrollRect.size) horizScroller:NO vertScroller:YES borderType:NX_BEZEL];
- contentRect.origin.x = contentRect.origin.y = 0.0;
- [diParmScrollView setDocView:[[View alloc] initFrame:&contentRect]];
-
- // add the Matrix to the docView of the scrollView
- [diParmNameMatrix getFrame:&matrixRect];
- matrixRect.origin.x = matrixRect.origin.y = 0.0;
- [diParmNameMatrix setFrame:&matrixRect];
- [[diParmScrollView docView] addSubview:diParmNameMatrix];
-
- diArgViewList = [[List alloc] init];
-
- // light inspector stuff...
- [distantLightView setImageFile:"distantLight"];
- [distantLightView setBorderType:1];
- [distantLightView setBackgroundColor:NXConvertRGBToColor(0.373, 0.298, 0.373)];
- [distantLightView setBackgroundAlpha:1.0];
- [distantLightView setLightType:N3D_DistantLight];
- //[distantLightView display];
-
- [pointLightView setImageFile:"pointLight"];
- [pointLightView setBorderType:1];
- [pointLightView setBackgroundColor:NXConvertRGBToColor(0.373, 0.298, 0.373)];
- [pointLightView setBackgroundAlpha:1.0];
- [pointLightView setLightType:N3D_PointLight];
- //[pointLightView display];
-
- [spotLightView setImageFile:"spotLight"];
- [spotLightView setBorderType:1];
- [spotLightView setBackgroundColor:NXConvertRGBToColor(0.373, 0.298, 0.373)];
- [spotLightView setBackgroundAlpha:1.0];
- [spotLightView setLightType:N3D_SpotLight];
- //[spotLightView display];
-
- // shape stuff
- // red: 255 81 107 == 1.00 .318 .420
- // green: 96 215 121 == .376 .843 .475
- // blue: 98 124 255 == .384 .486 1.00
-
- // need to set the interp input text fields so that they
- // have the right UI behavior
- [shapeInterpTextField setNextText:shapeInterpTextField];
- [cameraInterpTextField setNextText:cameraInterpTextField];
-
- // finally, make ourselves the delegate of the wellControlPanel,
- // so that when we get a performClose:, we know to nil out the outlet...
- [wellControlPanel setDelegate:self];
- }
- [ribParser setStatusText:statusText];
- [camera setStatusText:statusText];
- [camera setCurrentShape:[camera worldShape]];
- [shapeBrowser setTitled:NO];
- [[shapeBrowser loadColumnZero] selectRootShape];
-
- // okay, revert!
- [self revertControlPanel];
- [wellControlPanel display];
- [wellControlPanel makeKeyAndOrderFront:sender];
- [[camera worldShape] setVisible:YES];
- // display myself so that we see the shape again
- [self display]; NXPing();
-
- return self;
- }
-
- - mouseDown:(NXEvent *)theEvent
- { edgeClicked = YES;
- [statusText setStringValue:"loading control panel..."]; [statusText display]; NXPing();
- [self showControlPanel:nil];
- [statusText setStringValue:"done"]; [statusText display]; NXPing();
- return self;
- }
-
- - removeDefaultLights:sender { [camera removeDefaultLights]; [camera display]; return self; }
- - restoreDefaultLights:sender { [camera restoreDefaultLights]; [camera display]; return self; }
-
- - setRenderStartTime
- {
- gettimeofday(&renderStartTime, 0);
- return self;
- }
-
- - camera:theCamera didRenderStream:(NXStream *)imageStream tag:(int)jobTag frameNumber:(int)currentFrame
- {
- id newImage;
- long clock, tmpUsec;
- struct
- timeval elapsedTime;
- NXRect imageRect;
- NXSize windowSize;
-
-
- NXLogError("camera's delegate got called for renderJobTag %d\n", jobTag);
- gettimeofday(&renderFinishTime, 0);
- time(&clock);
- sprintf(timeBuf, "rendering job %d finished at %s", jobTag, ctime(&clock));
- if (renderHistoryText)
- { [renderHistoryText setSel:[renderHistoryText textLength] :[renderHistoryText textLength]];
- [renderHistoryText setSelGray:NX_BLACK];
- [renderHistoryText replaceSel:timeBuf];
- [renderHistoryText scrollSelToVisible];
- }
- [renderHistoryText display];
- NXPing();
-
- [self showImageView:nil];
- if (imageView)
- { newImage = [[NXImage alloc] initFromStream:imageStream];
- [imageView setImage:newImage];
- [imageView sizeToImage:nil];
- [imageView getFrame:&imageRect];
- [[imageView superview] sizeTo:imageRect.size.width :imageRect.size.height];
- //windowSize.width = imageRect.size.width + 2; // jeez, there must be a way to have the window do this...
- //windowSize.height = imageRect.size.height + 24; // boy, this is really dumb...
- windowSize.width = imageRect.size.width;
- windowSize.height = imageRect.size.height;
- [imageViewWindow sizeWindow:windowSize.width :windowSize.height];
- [imageViewWindow setMinSize:&windowSize];
- [imageViewWindow setMaxSize:&windowSize];
- [imageViewWindow setTitle:[imageView name]];
- [imageView sizeToImage:nil];
- [imageViewWindow makeKeyAndOrderFront:nil];
- }
-
- elapsedTime.tv_sec = renderFinishTime.tv_sec - renderStartTime.tv_sec;
- tmpUsec = renderFinishTime.tv_usec - renderStartTime.tv_usec;
- if (tmpUsec < 0)
- { elapsedTime.tv_sec--;
- elapsedTime.tv_usec = (long)1000000 + tmpUsec;
- }
- else
- { elapsedTime.tv_usec = tmpUsec;
- }
- if (elapsedTime.tv_usec > (long)1000000)
- { elapsedTime.tv_sec++;
- elapsedTime.tv_usec -= (long)1000000;
- }
-
- sprintf(timeBuf,
- "rendering took %d.%d seconds\n",
- (int)(elapsedTime.tv_sec), (int)(1000000 - elapsedTime.tv_usec));
- if (renderHistoryText)
- { [renderHistoryText setSel:[renderHistoryText textLength] :[renderHistoryText textLength]];
- [renderHistoryText setSelGray:NX_BLACK];
- [renderHistoryText replaceSel:timeBuf];
- [renderHistoryText scrollSelToVisible];
- }
- [renderHistoryText display];
- NXPing();
-
- return self;
- }
-
- - renderItUsing3DKit:sender
- {
- long clock;
-
-
- // so here's the idea: if the camera's got a crop/selection window
- // up, we use that, otherwise we want to render the whole thing.
- //
-
- [camera setBackgroundRenderingOff];
- time(&clock);
- sprintf(timeBuf, "rendering started at %s", ctime(&clock));
- if (renderHistoryText)
- { [renderHistoryText setSel:[renderHistoryText textLength] :[renderHistoryText textLength]];
- [renderHistoryText setSelGray:NX_BLACK];
- [renderHistoryText replaceSel:timeBuf];
- }
- [renderHistoryText display];
- NXPing();
- gettimeofday(&renderStartTime, 0);
- renderJobTag = [camera renderAsTIFF];
- NXLogError("my renderJobTag is %d\n", renderJobTag);
-
- return self;
- }
-
-
-
- // really should make this be the rendering command and the file be variables, so you could do something like:
- // system("rsh yoshi /usr/local/prman/bin/prman /cga/tmp/foo.rib")
- // actually, it should be a thread off by itself. If Springer had made this easy in the first place, argh....
-
- - renderItBlocking:sender
- {
- long clock, tmpUsec;
- struct
- timeval elapsedTime;
- char tmpRIBFilename[64], tmpTIFFFilename[64];
- char cmd[128], windowTitle[256];
- //id aRenderWrangler;
- NXRect imageRect;
- NXSize windowSize;
- int ret;
-
-
- [camera setBackgroundRenderingOff];
- // so here's the idea: if the camera's got a crop/selection window
- // up, we use that, otherwise we want to render the whole thing.
- //
- sprintf(tmpRIBFilename, "/tmp/foo%d.rib", getpid());
- sprintf(tmpTIFFFilename, "/tmp/foo%d.tiff", getpid());
- [camera dumpRIBToFile:tmpRIBFilename];
- time(&clock);
- sprintf(timeBuf, "rendering started at %s", ctime(&clock));
- if (renderHistoryText)
- { [renderHistoryText setSel:[renderHistoryText textLength] :[renderHistoryText textLength]];
- [renderHistoryText setSelGray:NX_BLACK];
- [renderHistoryText replaceSel:timeBuf];
- [renderHistoryText scrollSelToVisible];
- }
- [renderHistoryText display];
- NXPing();
- gettimeofday(&renderStartTime, 0);
-
- if ([self useRendribInstead])
- { sprintf(cmd, "rendrib %s", tmpRIBFilename);
- }
- else
- { sprintf(cmd, "/usr/prman/prman %s", tmpRIBFilename);
- }
-
- ret = system(cmd);
- if (ret)
- { sprintf(timeBuf, "rendering finished at %s\nwith an error of %d (check Workspace's Console for more details.\n", ctime(&clock), ret);
- if (renderHistoryText)
- { [renderHistoryText setSel:[renderHistoryText textLength] :[renderHistoryText textLength]];
- [renderHistoryText setSelColor:NX_COLORRED];
- [renderHistoryText replaceSel:timeBuf];
- [renderHistoryText scrollSelToVisible];
- }
- [renderHistoryText display];
- NXBeep(); NXBeep();
- NXPing();
- return nil;
- }
-
- //aRenderWrangler = [[WWRenderWrangler alloc] init];
- //[aRenderWrangler setCmd:cmd];
- //[aRenderWrangler setBoss:self];
- //cthread_detach(cthread_fork(renderItDude, aRenderWrangler));
-
- gettimeofday(&renderFinishTime, 0);
- time(&clock);
- sprintf(timeBuf, "rendering finished at %s", ctime(&clock));
- if (renderHistoryText)
- { [renderHistoryText setSel:[renderHistoryText textLength] :[renderHistoryText textLength]];
- [renderHistoryText setSelGray:NX_BLACK];
- [renderHistoryText replaceSel:timeBuf];
- [renderHistoryText scrollSelToVisible];
- }
- [renderHistoryText display];
- NXPing();
-
- elapsedTime.tv_sec = renderFinishTime.tv_sec - renderStartTime.tv_sec;
- tmpUsec = renderFinishTime.tv_usec - renderStartTime.tv_usec;
- if (tmpUsec < 0)
- { elapsedTime.tv_sec--;
- elapsedTime.tv_usec = (long)1000000 + tmpUsec;
- }
- else
- { elapsedTime.tv_usec = tmpUsec;
- }
- if (elapsedTime.tv_usec > (long)1000000)
- { elapsedTime.tv_sec++;
- elapsedTime.tv_usec -= (long)1000000;
- }
-
- // open up the proto nib with a movieView in it.
- [self showImageView:nil];
-
- [imageView setImage:[[NXImage alloc] initFromFile:tmpTIFFFilename]];
- [imageView sizeToImage:nil];
- [imageView getFrame:&imageRect];
- [[imageView superview] sizeTo:imageRect.size.width :imageRect.size.height];
- //windowSize.width = imageRect.size.width + 2; // jeez, there must be a way to have the window do this...
- //windowSize.height = imageRect.size.height + 24; // boy, this is really dumb...
- windowSize.width = imageRect.size.width;
- windowSize.height = imageRect.size.height;
- [imageViewWindow sizeWindow:windowSize.width :windowSize.height];
- [imageViewWindow setMinSize:&windowSize];
- [imageViewWindow setMaxSize:&windowSize];
-
- if ([self useRendribInstead])
- { sprintf(windowTitle, "(%d.%dsec w/rendrib)",
- (int)(elapsedTime.tv_sec), (int)((1000000 - elapsedTime.tv_usec)/100000));
- }
- else
- { sprintf(windowTitle, "(%d.%dsec@%3.2fshadingRate)",
- (int)(elapsedTime.tv_sec), (int)((1000000 - elapsedTime.tv_usec)/100000), [self shadingRate]);
- }
- [imageViewWindow setTitle:windowTitle];
- [imageView sizeToImage:nil];
- [imageViewWindow makeKeyAndOrderFront:nil];
-
- sprintf(timeBuf,
- "rendering took %d.%d seconds\n",
- (int)(elapsedTime.tv_sec), (int)((1000000 - elapsedTime.tv_usec)/100000));
- if (renderHistoryText)
- { [renderHistoryText setSel:[renderHistoryText textLength] :[renderHistoryText textLength]];
- [renderHistoryText setSelGray:NX_BLACK];
- [renderHistoryText replaceSel:timeBuf];
- [renderHistoryText scrollSelToVisible];
- }
- [renderHistoryText display];
- if (beepWhenDone) { NXBeep(); }
- NXPing();
- return self;
- }
-
- - saveImage:sender { return [camera saveImage:sender]; }
-
- - dumpRIB:sender { return [camera dumpRIB:sender]; }
-
- - dumpShot:sender { return [camera dumpShotToRIB:sender]; }
-
- - dumpEve:sender { return [camera dumpEve:sender]; }
-
- - dumpScene:sender { return [camera dumpScene:sender]; }
-
- - dump3DTextScene:sender { return [camera dump3DTextScene:sender]; }
-
- - dumpInventor:sender { return [camera dumpInventor:sender]; }
-
- - dumpSceneGraph:sender
- {
- // this one, I'm gonna do
-
- // First of all, we need to find out the "oldest" sample in the current scene.
- //
-
- return self;
- }
-
-
- // really should make this be the rendering command and the file be variables, so you could do something like:
- // system("rsh yoshi /usr/local/prman/bin/prman /cga/tmp/foo.rib")
-
- - renderShotBlocking:sender
- {
- long clock, tmpUsec;
- struct
- timeval elapsedTime;
- char tmpAnimDir[128], tmpRIBFilename[128];
- char cmd[128];
-
-
- [camera setBackgroundRenderingOff];
- // so here's the idea: if the camera's got a crop/selection window
- // up, we use that, otherwise we want to render the whole thing.
- //
- sprintf(tmpAnimDir, "/tmp/foo%d.anim", getpid());
- sprintf(cmd, "mkdirs %s", tmpAnimDir);
- system(cmd);
- sprintf(tmpRIBFilename, "%s/foo%d.rib", tmpAnimDir, getpid());
- [camera dumpShotToRIBFile:tmpRIBFilename];
- time(&clock);
- sprintf(timeBuf, "rendering started at %s", ctime(&clock));
- if (renderHistoryText)
- { [renderHistoryText setSel:[renderHistoryText textLength] :[renderHistoryText textLength]];
- [renderHistoryText setSelGray:NX_BLACK];
- [renderHistoryText replaceSel:timeBuf];
- [renderHistoryText scrollSelToVisible];
- }
- [renderHistoryText display];
- NXPing();
- gettimeofday(&renderStartTime, 0);
-
- sprintf(cmd, "/usr/prman/prman %s", tmpRIBFilename);
-
-
- // at this point, we want to fork a thread to actually render this guy.
-
- system(cmd);
- //cthread_detach(cthread_fork(evalCmdUsingSystem, cmd));
-
-
- gettimeofday(&renderFinishTime, 0);
- time(&clock);
- sprintf(timeBuf, "rendering finished at %s", ctime(&clock));
- if (renderHistoryText)
- { [renderHistoryText setSel:[renderHistoryText textLength] :[renderHistoryText textLength]];
- [renderHistoryText setSelGray:NX_BLACK];
- [renderHistoryText replaceSel:timeBuf];
- [renderHistoryText scrollSelToVisible];
- }
- [renderHistoryText display];
- NXPing();
- [self showImageView:nil];
- [imageView setAnimDir:tmpAnimDir];
-
- elapsedTime.tv_sec = renderFinishTime.tv_sec - renderStartTime.tv_sec;
- tmpUsec = renderFinishTime.tv_usec - renderStartTime.tv_usec;
- if (tmpUsec < 0)
- { elapsedTime.tv_sec--;
- elapsedTime.tv_usec = (long)1000000 + tmpUsec;
- }
- else
- { elapsedTime.tv_usec = tmpUsec;
- }
- if (elapsedTime.tv_usec > (long)1000000)
- { elapsedTime.tv_sec++;
- elapsedTime.tv_usec -= (long)1000000;
- }
-
- sprintf(timeBuf,
- "rendering took %d.%d seconds\n",
- (int)(elapsedTime.tv_sec), (int)(1000000 - elapsedTime.tv_usec));
- if (renderHistoryText)
- { [renderHistoryText setSel:[renderHistoryText textLength] :[renderHistoryText textLength]];
- [renderHistoryText setSelGray:NX_BLACK];
- [renderHistoryText replaceSel:timeBuf];
- [renderHistoryText scrollSelToVisible];
- }
- [renderHistoryText display];
- NXPing();
- return self;
- }
-
- //
- - addShape:sender
- {
- id theOpenPanel;
- const char *filename;
- char *extension,
- *filterTypes[6] = {"eve", "rib", "mdl", "wwModel", "wwScene", NULL };
-
-
- theOpenPanel = [OpenPanel new];
- [theOpenPanel allowMultipleFiles:NO];
- if (![theOpenPanel runModalForTypes:filterTypes])
- { return nil;
- }
-
- filename = [theOpenPanel filename];
- extension = (char *)filename + (strlen(filename) - 4);
- if ((filename) && (!strcmp(".rib", extension)))
- { [self addToShapeHierarchyFromRIBFile:filename];
- }
- if ((filename) && (!strcmp(".eve", extension)))
- { [self addToShapeHierarchyFromEveFile:filename];
- }
- if ((filename) && (!strcmp(".mdl", extension)))
- { [self addToShapeHierarchyFromMdlFile:filename];
- }
-
- extension = (char *)filename + (strlen(filename) - 8);
- if ((filename) && (!strcmp(".wwModel", extension)))
- { [self addToShapeHierarchyFromMdlFile:filename];
- }
- if ((filename) && (!strcmp(".wwScene", extension)))
- { [self addToShapeHierarchyFromSceneFile:filename];
- }
- return self;
- }
- //
- - replaceWorldShape:sender
- {
- id theOpenPanel;
- const char *filename;
- char *extension,
- *filterTypes[6] = {"eve", "rib", "mdl", "wwModel", "wwScene", NULL };
-
-
- theOpenPanel = [OpenPanel new];
- [theOpenPanel allowMultipleFiles:NO];
- if (![theOpenPanel runModalForTypes:filterTypes])
- { return nil;
- }
-
- filename = [theOpenPanel filename];
- extension = (char *)filename + (strlen(filename) - 4);
- if ((filename) && (!strcmp(".rib", extension)))
- { [self buildNewShapeHierarchyFromRIBFile:filename];
- }
- if ((filename) && (!strcmp(".eve", extension)))
- { [self buildNewShapeHierarchyFromEveFile:filename];
- }
- if ((filename) && (!strcmp(".mdl", extension)))
- { [self buildNewShapeHierarchyFromMdlFile:filename];
- }
-
- extension = (char *)filename + (strlen(filename) - 8);
- if ((filename) && (!strcmp(".wwModel", extension)))
- { [self addToShapeHierarchyFromMdlFile:filename];
- }
- if ((filename) && (!strcmp(".wwScene", extension)))
- { [self addToShapeHierarchyFromSceneFile:filename];
- }
-
- return self;
- }
-
- - loadNibForModelInterp:(const char *)nibFilename
- { return [[ribParser tclInterp] loadControlPanel:(char *)nibFilename modally:NO];
- }
-
- - loadNibForCameraInterp:(const char *)nibFilename
- { return [[camera tclInterp] loadControlPanel:(char *)nibFilename modally:NO];
- }
-
- - revertSurfaceShaderInspectorFor:s
- {
- int i, howManyCells, howManyArgs;
- RtPoint pValue;
- float fValue;
- NXColor cValue;
- char *sValue;
- SLO_TYPE argType, shaderType;
- id newCell, newArgView;
- NXRect argViewFrame, matrixFrame, superFrame;
- NXSize cellSize, intercellSize;
-
-
- howManyArgs = [s shaderArgCount];
- shaderType = [s shaderType];
-
- [suNameText setStringValue:[s shader]];
-
- // get the scrollView's docView
- // need to make a
- suParmView = [suParmScrollView docView];
-
- [suParmNameMatrix setAutoscroll:YES];
- [suParmNameMatrix setScrollable:YES];
-
- [suParmNameMatrix getFrame:&matrixFrame];
- [suParmNameMatrix getCellSize:&cellSize];
- [suParmNameMatrix getIntercell:&intercellSize];
- // don't want any intercell spacing between arg views
- argViewFrame.size.width = cellSize.width - 1;
- argViewFrame.size.height = cellSize.height + intercellSize.height;
- argViewFrame.origin.x = matrixFrame.size.width;
- argViewFrame.origin.y = (howManyArgs - 1) * argViewFrame.size.height;
-
- // clear things out...
- howManyCells = [[suParmNameMatrix cellList] count];
- for (i = 0; i < howManyCells; i++)
- { [suParmNameMatrix removeRowAt:0 andFree:YES];
- [suParmNameMatrix sizeToCells];
- }
- [suArgViewList freeObjects];
-
- // need to tell the Matrix's superview to resize itself to (howManyArgs*argViewFrame.size.height)
- [[suParmNameMatrix superview] getFrame:&superFrame];
- [[suParmNameMatrix superview] sizeTo:superFrame.size.width :(howManyArgs*argViewFrame.size.height)];
-
- for (i = 0; i < howManyArgs; i++)
- { // build up the new one...
- [suParmNameMatrix addRow];
- [suParmNameMatrix sizeToCells];
- newCell = [suParmNameMatrix cellAt:i :0];
- [newCell setStringValue:[s shaderArgNameAt:i]];
- [newCell setAlignment:NX_RIGHTALIGNED];
-
- // now we need to build up the args...
- argType = [s shaderArgType:[s shaderArgNameAt:i]];
- switch (argType) {
- case SLO_TYPE_POINT: [s getShaderArg:[s shaderArgNameAt:i] pointValue:&pValue];
- NXLogError("\targName:%s type:point value:(%f %f %f)\n",
- [s shaderArgNameAt:i], N3D_XComp(pValue), N3D_YComp(pValue), N3D_ZComp(pValue));
- break;
- case SLO_TYPE_COLOR: [s getShaderArg:[s shaderArgNameAt:i] colorValue:&cValue];
- newArgView = [[WWShaderArgColorWell alloc] initFrame:&argViewFrame];
- [newArgView setShaderArgName:[s shaderArgNameAt:i]];
- [newArgView setTarget:s];
- [newArgView setAction:@selector(takeColorArg:)];
- [newArgView setColor:cValue];
- [suParmView addSubview:newArgView];
- [suArgViewList addObject:newArgView];
- break;
- case SLO_TYPE_SCALAR: [s getShaderArg:[s shaderArgNameAt:i] floatValue:&fValue];
- newArgView = [[WWShaderArgTextField alloc] initFrame:&argViewFrame];
- [newArgView setShaderArgName:[s shaderArgNameAt:i]];
- [newArgView setTarget:s];
- [newArgView setAction:@selector(takeFloatArg:)];
- [newArgView setFloatValue:fValue];
- [suParmView addSubview:newArgView];
- [suArgViewList addObject:newArgView];
- break;
- case SLO_TYPE_STRING: [s getShaderArg:[s shaderArgNameAt:i] stringValue:&sValue];
- newArgView = [[WWShaderArgTextField alloc] initFrame:&argViewFrame];
- [newArgView setShaderArgName:[s shaderArgNameAt:i]];
- [newArgView setTarget:s];
- [newArgView setAction:@selector(takeStringArg:)];
- [newArgView setStringValue:sValue];
- [suParmView addSubview:newArgView];
- [suArgViewList addObject:newArgView];
- break;
- default: NXLogError("\targName:%s type:UNKNOWN\n", [s shaderArgNameAt:i]);
- break;
- }
- argViewFrame.origin.y -= argViewFrame.size.height;
- }
- [suParmView display];
-
-
-
- return self;
- }
-
- - revertDisplacementShaderInspectorFor:s
- {
- int i, howManyCells, howManyArgs;
- RtPoint pValue;
- float fValue;
- NXColor cValue;
- char *sValue;
- SLO_TYPE argType, shaderType;
- id newCell, newArgView;
- NXRect argViewFrame, matrixFrame, superFrame;
- NXSize cellSize, intercellSize;
-
-
- howManyArgs = [s shaderArgCount];
- shaderType = [s shaderType];
-
- [diNameText setStringValue:[s shader]];
-
- // get the scrollView's docView
- // need to make a
- diParmView = [diParmScrollView docView];
-
- [diParmNameMatrix setAutoscroll:YES];
- [diParmNameMatrix setScrollable:YES];
-
- [diParmNameMatrix getFrame:&matrixFrame];
- [diParmNameMatrix getCellSize:&cellSize];
- [diParmNameMatrix getIntercell:&intercellSize];
- // don't want any intercell spacing between arg views
- argViewFrame.size.width = cellSize.width - 1;
- argViewFrame.size.height = cellSize.height + intercellSize.height;
- argViewFrame.origin.x = matrixFrame.size.width;
- argViewFrame.origin.y = (howManyArgs - 1) * argViewFrame.size.height;
-
- // clear things out...
- howManyCells = [[diParmNameMatrix cellList] count];
- for (i = 0; i < howManyCells; i++)
- { [diParmNameMatrix removeRowAt:0 andFree:YES];
- [diParmNameMatrix sizeToCells];
- }
- [diArgViewList freeObjects];
-
- // need to tell the Matrix's superview to resize itself to (howManyArgs*argViewFrame.size.height)
- [[diParmNameMatrix superview] getFrame:&superFrame];
- [[diParmNameMatrix superview] sizeTo:superFrame.size.width :(howManyArgs*argViewFrame.size.height)];
-
- for (i = 0; i < howManyArgs; i++)
- { // build up the new one...
- [diParmNameMatrix addRow];
- [diParmNameMatrix sizeToCells];
- newCell = [diParmNameMatrix cellAt:i :0];
- [newCell setStringValue:[s shaderArgNameAt:i]];
- [newCell setAlignment:NX_RIGHTALIGNED];
-
- // now we need to build up the args...
- argType = [s shaderArgType:[s shaderArgNameAt:i]];
- switch (argType) {
- case SLO_TYPE_POINT: [s getShaderArg:[s shaderArgNameAt:i] pointValue:&pValue];
- NXLogError("\targName:%s type:point value:(%f %f %f)\n",
- [s shaderArgNameAt:i], N3D_XComp(pValue), N3D_YComp(pValue), N3D_ZComp(pValue));
- break;
- case SLO_TYPE_COLOR: [s getShaderArg:[s shaderArgNameAt:i] colorValue:&cValue];
- newArgView = [[WWShaderArgColorWell alloc] initFrame:&argViewFrame];
- [newArgView setShaderArgName:[s shaderArgNameAt:i]];
- [newArgView setTarget:s];
- [newArgView setAction:@selector(takeColorArg:)];
- [newArgView setColor:cValue];
- [diParmView addSubview:newArgView];
- [diArgViewList addObject:newArgView];
- break;
- case SLO_TYPE_SCALAR: [s getShaderArg:[s shaderArgNameAt:i] floatValue:&fValue];
- newArgView = [[WWShaderArgTextField alloc] initFrame:&argViewFrame];
- [newArgView setShaderArgName:[s shaderArgNameAt:i]];
- [newArgView setTarget:s];
- [newArgView setAction:@selector(takeFloatArg:)];
- [newArgView setFloatValue:fValue];
- [diParmView addSubview:newArgView];
- [diArgViewList addObject:newArgView];
- break;
- case SLO_TYPE_STRING: [s getShaderArg:[s shaderArgNameAt:i] stringValue:&sValue];
- newArgView = [[WWShaderArgTextField alloc] initFrame:&argViewFrame];
- [newArgView setShaderArgName:[s shaderArgNameAt:i]];
- [newArgView setTarget:s];
- [newArgView setAction:@selector(takeStringArg:)];
- [newArgView setStringValue:sValue];
- [diParmView addSubview:newArgView];
- [diArgViewList addObject:newArgView];
- break;
- default: NXLogError("\targName:%s type:UNKNOWN\n", [s shaderArgNameAt:i]);
- break;
- }
- argViewFrame.origin.y -= argViewFrame.size.height;
- }
- [diParmView display];
-
- return self;
- }
-
- - takeSuColor:sender
- {
- [[[camera currentShape] shaderType:SLO_TYPE_SURFACE] setColor:[sender color]];
- return self;
- }
-
- - takeDiColor:sender
- {
- [[[camera currentShape] shaderType:SLO_TYPE_DISPLACEMENT] setColor:[sender color]];
- return self;
- }
-
- - drawRtMatrix:(RtMatrix)anRtMatrix inMatrix:aMatrix
- {
- int i, j;
-
-
- for (i = 0; i < 4; i++)
- { for (j = 0; j < 4; j++)
- { [[aMatrix cellAt:i :j] setFloatValue:anRtMatrix[i][j]];
- }
- }
- return self;
- }
-
- - fillRIBCommandsMatrix:theMatrix
- {
- int howMany, i;
- id newCell;
- const char *className;
-
-
- howMany = [[theMatrix cellList] count];
- for (i = 0; i < howMany; i++)
- { [theMatrix removeRowAt:0 andFree:YES];
- [theMatrix sizeToCells];
- }
- howMany = [[[camera currentShape] ribCommands] count];
- for (i = 0; i < howMany; i++)
- { [theMatrix addRow];
- [theMatrix sizeToCells];
- newCell = [theMatrix cellAt:i :0];
- //Note: these really should be double-clickable themselves...
- // need to find out the class name of the cell
- // if it's an EveCommand, we need to get the class name of the firstSample
- // we'll enclose that in ()
- // if it's an EveProc, we need to get the name of the proc
- // we'll enclose that in {}
- className = [[[[[camera currentShape] ribCommands] objectAt:i] class] name];
- if (!strcmp(className, "EveCommand") || !strcmp(className, "EveProc"))
- { className = [[[[camera currentShape] ribCommands] objectAt:i] sampleName];
- }
- [newCell setStringValue:className];
- }
-
- return self;
- }
-
- //
- - removeSurfaceShader:sender
- {
- [[camera currentShape] removeSurfaceShader:sender];
- [self revertSurfaceShaderInspectorFor:nil];
- [delegate sceneWasUpdated:camera];
- [self display];
- return self;
- }
-
- - removeDisplacementShader:sender
- {
- [[camera currentShape] removeDisplacementShader:sender];
- [self revertDisplacementShaderInspectorFor:nil];
- [delegate sceneWasUpdated:camera];
- [self display];
- return self;
- }
-
- - addShader:sender
- {
- id theOpenPanel;
- const char *filename;
- char *extension,
- *filterTypes[3] = {"slo", "WW3DShader", NULL };
- id newShader;
- static char shaderName[256];
-
-
- theOpenPanel = [OpenPanel new];
- [theOpenPanel allowMultipleFiles:NO];
- if (![theOpenPanel runModalForDirectory:"/LocalLibrary/Shaders" file:NULL types:filterTypes])
- { return self;
- }
-
- filename = [theOpenPanel filename];
- extension = (char *)filename + (strlen(filename) - 4);
- if ((filename) && (!strcmp(".slo", extension)))
- { basename(filename, ".slo", shaderName);
- if ((newShader = [(WW3DShader *)[[WW3DShader alloc] init] setShader:shaderName]))
- { [[camera currentShape] setShader_:newShader];
- }
-
- // at this point, we want to ask the shader to describe its
- // arguments to us, and construct an inspector for it which gets put on
- // it the control panel
- if ([newShader shaderType] == SLO_TYPE_SURFACE)
- { [self revertSurfaceShaderInspectorFor:newShader];
- }
- if ([newShader shaderType] == SLO_TYPE_DISPLACEMENT)
- { [self revertDisplacementShaderInspectorFor:newShader];
- }
-
- [delegate sceneWasUpdated:camera];
- [self display];
- }
- else
- { return nil;
- }
- return self;
- }
-
- - addSurfaceShader:sender
- {
- id theOpenPanel;
- const char *filename;
- char *extension,
- *filterTypes[3] = {"slo", "WW3DShader", NULL };
- id newShader;
- static char shaderName[256];
-
-
- theOpenPanel = [OpenPanel new];
- [theOpenPanel allowMultipleFiles:NO];
- if (![theOpenPanel runModalForDirectory:"/LocalLibrary/Shaders" file:NULL types:filterTypes])
- { return self;
- }
-
- filename = [theOpenPanel filename];
- extension = (char *)filename + (strlen(filename) - 4);
- if ((filename) && (!strcmp(".slo", extension)))
- { basename(filename, ".slo", shaderName);
- if (!(newShader = [(WW3DShader *)[[WW3DShader alloc] init] setShader:shaderName]))
- { return nil;
- }
-
- // at this point, we want to ask the shader to describe its
- // arguments to us, and construct an inspector for it which gets put on
- // it the control panel
- if ([newShader shaderType] == SLO_TYPE_SURFACE)
- { [[camera currentShape] setShader_:newShader];
- [self revertSurfaceShaderInspectorFor:newShader];
- [delegate sceneWasUpdated:camera];
- [self display];
- }
- else
- { NXLogError("%s is not a surface shader\n", shaderName);
- [newShader free];
- return nil;
- }
- }
- else
- { return nil;
- }
- return self;
- }
-
- - addDisplacementShader:sender
- {
- id theOpenPanel;
- const char *filename;
- char *extension,
- *filterTypes[3] = {"slo", "WW3DShader", NULL };
- id newShader;
- static char shaderName[256];
-
-
- theOpenPanel = [OpenPanel new];
- [theOpenPanel allowMultipleFiles:NO];
- if (![theOpenPanel runModalForDirectory:"/LocalLibrary/Shaders" file:NULL types:filterTypes])
- { return self;
- }
-
- filename = [theOpenPanel filename];
- extension = (char *)filename + (strlen(filename) - 4);
- if ((filename) && (!strcmp(".slo", extension)))
- { basename(filename, ".slo", shaderName);
- if (!(newShader = [(WW3DShader *)[[WW3DShader alloc] init] setShader:shaderName]))
- { return nil;
- }
-
- // at this point, we want to ask the shader to describe its
- // arguments to us, and construct an inspector for it which gets put on
- // it the control panel
- if ([newShader shaderType] == SLO_TYPE_DISPLACEMENT)
- { [[camera currentShape] setShader_:newShader];
- [self revertDisplacementShaderInspectorFor:newShader];
- [delegate sceneWasUpdated:camera];
- [self display];
- }
- else
- { NXLogError("%s is not a displacement shader\n", shaderName);
- [newShader free];
- return nil;
- }
- }
- else
- { return nil;
- }
- return self;
- }
-
-
- // inspector/control panel methods
- //
- - (RtFloat)tesselation { return [camera tesselation]; }
- - takeTesselation:sender { [camera takeTesselation:sender]; return [self revertControlPanel]; }
- //
- - (NXColor)backgroundColor { return [camera backgroundColor]; }
- - takeWellBackgroundColor:sender { [camera setBackgroundColor:[sender color]]; return [self revertControlPanel]; }
- //
- - (RtFloat)lowRezTesselation { return [camera lowRezTesselation]; }
- - takeLowRezTesselation:sender { [camera takeLowRezTesselation:sender]; return [self revertControlPanel]; }
- //
- - (RtFloat)shadingRate { return [camera shadingRate]; }
- // don't bother reverting the control panel for this one
- - takeShadingRate:sender
- { [camera takeShadingRate:sender];
- [delegate sceneWasUpdated:camera];
- // rather than revert the whole control panel, just do these two...
- [shadingRateText setFloatValue:[camera shadingRate]];
- [shadingRateSlider setFloatValue:[camera shadingRate]];
- return self;
- }
- //
- - (BOOL)firmTransforms { return [ribParser firmTransforms]; }
- - takeFirmTransforms:sender { [ribParser takeFirmTransforms:sender]; return [self revertControlPanel]; }
- //
- - (BOOL)ignoreShadingRate { return [ribParser ignoreShadingRate]; }
- - takeIgnoreShadingRate:sender { [ribParser setIgnoreShadingRate:sender]; return [self revertControlPanel]; }
- //
- - (BOOL)ignoreColors { return [ribParser ignoreColors]; }
- - takeIgnoreColors:sender { [ribParser setIgnoreColors:sender]; return [self revertControlPanel]; }
- //
- - (BOOL)ignoreShaders { return [ribParser ignoreShaders]; }
- - takeIgnoreShaders:sender { [ribParser setIgnoreShaders:sender]; return [self revertControlPanel]; }
- //
- - (BOOL)ignoreLights { return [ribParser ignoreLights]; }
- - takeIgnoreLights:sender { [ribParser setIgnoreLights:sender]; return [self revertControlPanel]; }
- //
- - (NXColor)selectedColor { return selectedColor; }
- - takeSelectedColor:sender { return self; }
- //
- - (NXColor)unselectedColor { return unselectedColor; }
- - takeUnselectedColor:sender { return self; }
- //
- - (float)fov { return [camera fieldOfView]; }
- - takeFOV:sender
- { float fov = [sender floatValue];
-
- if (fov < 0.0)
- { fov = 0.0;
- }
- if (fov > 180.0)
- { fov = 180.0;
- }
- [camera setFieldOfViewByAngle:fov];
- [self revertControlPanel];
- [delegate sceneWasUpdated:camera];
- [self display];
- return self;
- }
- //
- - (int)aspectRatioType { return aspectRatioType; }
- - (float)aspectRatio { return aspectRatio; }
- - setCustomAspectRatioText:newCustomAspectRatioText { customAspectRatioText = newCustomAspectRatioText; return self; }
- - takeAspectRatioFromMatrix:sender
- {
- NXRect newRect;
-
-
- [self getFrame:&newRect];
- aspectRatioType = [[sender selectedCell] tag];
- switch (aspectRatioType)
- { case WW_ASPECT_DONT_CARE:
- [customAspectRatioText setEnabled:NO];
- break;
- case WW_ASPECT_NTSC: // 1.33:1
- [customAspectRatioText setEnabled:NO];
- newRect.size.height = newRect.size.width/1.33;
- break;
- case WW_ASPECT_AMERICAN_WIDESCREEN: // 1.85:1
- [customAspectRatioText setEnabled:NO];
- newRect.size.height = newRect.size.width/1.85;
- break;
- case WW_ASPECT_EUROPEAN_WIDESCREEN: // 1.66:1
- [customAspectRatioText setEnabled:NO];
- newRect.size.height = newRect.size.width/1.66;
- break;
- case WW_ASPECT_VISTA_VISION: // 2.21:1
- [customAspectRatioText setEnabled:NO];
- newRect.size.height = newRect.size.width/2.21;
- break;
- case WW_ASPECT_SQUARE: // 1:1
- [customAspectRatioText setEnabled:NO];
- if (newRect.size.width < newRect.size.height)
- { newRect.size.height = newRect.size.width;
- }
- else
- { newRect.size.width = newRect.size.height;
- }
- break;
- case WW_ASPECT_CUSTOM: //aspectX:aspectY
- [customAspectRatioText setEnabled:YES];
- aspectRatio = [customAspectRatioText floatValue];
- if (aspectRatio < 1.0)
- { newRect.size.width = newRect.size.height * aspectRatio;
- }
- else
- { newRect.size.height = newRect.size.width/aspectRatio;
- }
- break;
- default:
- [customAspectRatioText setEnabled:NO];
- NXLogError("unknown aspect ratio type: %d", aspectRatioType);
- break;
- }
- [self sizeTo:newRect.size.width :newRect.size.height];
- [delegate sceneWasUpdated:camera];
- [self revertControlPanel];
-
- return self;
- }
- //
- - takeAspectRatio:sender
- {
- NXRect newRect;
-
-
- [self getFrame:&newRect];
- aspectRatio = [sender floatValue];
-
- if (aspectRatioType != WW_ASPECT_CUSTOM)
- { [self revertControlPanel];
- return self;
- }
- if (aspectRatio < 1.0)
- { newRect.size.width = newRect.size.height * aspectRatio;
- }
- else
- { newRect.size.height = newRect.size.width/aspectRatio;
- }
- [self sizeTo:newRect.size.width :newRect.size.height];
- [delegate sceneWasUpdated:camera];
- [self revertControlPanel];
-
- return self;
- }
- //
- - (N3DProjectionType)projectionType { return projectionType; }
- - takeProjectionTypeFromMatrix:sender
- {
- int theProjectionType = [[sender selectedCell] tag];
-
-
- switch (theProjectionType)
- { case N3D_Perspective:
- projectionType = theProjectionType;
- break;
- case N3D_Orthographic:
- projectionType = theProjectionType;
- break;
- default:
- NXLogError("unknown projection type: %d", theProjectionType);
- break;
- }
- [camera setProjection:projectionType];
- [delegate sceneWasUpdated:camera];
- [self revertControlPanel];
- [window display];
-
- return self;
- }
-
- - takeInitialGeometry:sender
- {
- char *name = (char *)[sender stringValue], *extension;
-
-
- // must be at least x.rib or x.eve
- if (!*name || (strlen(name) < 5))
- { return nil;
- }
- extension = name + (strlen(name) - 4);
- if (!strcmp(extension, ".eve"))
- { return [self buildNewShapeHierarchyFromEveFile:name];
- }
- if (!strcmp(extension, ".rib"))
- { return [self buildNewShapeHierarchyFromRIBFile:name];
- }
-
- return nil;
- }
-
- - takeInitialImage:sender { return [camera setImageFile:[sender stringValue]]; }
- - takeInitialImageFile:(const char *)n { return [camera setImageFile:n]; }
-
- - (int)trackballAffects { return [camera trackballAffects]; }
- - takeTrackballAffectsFromMatrix:sender { return [camera takeTrackballAffectsFromMatrix:sender]; }
-
- - (int)trackballXYZ { return [camera trackballXYZ]; }
- - takeTrackballXYZFromMatrix:sender { return [camera takeTrackballXYZFromMatrix:sender]; }
-
-
- // history stuff
- - takeStatusText:sender { statusText = sender; return [camera takeStatusText:sender]; }
-
-
- // scene clock stuff
- - takeSceneClockTime:sender { [sceneClock setCurrentTime:[sender floatValue]]; return self; }
- - takeSceneClockSamplesPerSecond:sender { [sceneClock setSamplesPerSecond:[sender floatValue]]; return self; }
- - takeSceneClockIncrement:sender { [sceneClock setIncrement:[sender floatValue]]; return self; }
- - takeSceneClockSkip:sender { [sceneClock setSkip:[sender floatValue]]; return self; }
- - takeSceneClockRatio:sender { [sceneClock setRatio:[sender floatValue]]; return self; }
- - takeSceneClockMark:sender { [sceneClock takeMark:sender]; return self; }
- // scene clock informal protocol
- - rewind:sender { [sceneClock rewind:sender]; return self; }
- - pause:sender { [sceneClock pause:sender]; return self; }
- - play:sender { [sceneClock play:sender]; return self; }
- - increment:sender { [sceneClock increment:sender]; return self; }
- - decrement:sender { [sceneClock decrement:sender]; return self; }
- - fastForward:sender { [sceneClock fastForward:sender]; return self; }
- - takeMark:sender { [sceneClock takeMark:sender]; return self; }
- - findLastSampleAndSetMark:sender { [sceneClock setMark:[[camera worldShape] lastSampleIsAt]]; return self; }
-
- ////////////////////////////////////////////////////////////////////
- // Dragging stuff
- ///////////////////////////////////////////////////////////////////
-
- - (NXDragOperation)draggingEntered:(id <NXDraggingInfo>)sender
- {
- Pasteboard *pboard;
- char *argv;
- int len;
- const NXAtom *theType;
- char *extension;
- NXEvent *theEvent = [NXApp currentEvent];
-
-
- pboard = [sender draggingPasteboard];
- theType = [pboard types];
-
- if (*theType != NXFilenamePboardType)
- { if ([pboard readType:NXFilenamePboardType data:&argv length:&len] == nil)
- { fprintf(stderr, "unable to read filename from pasteboard.\n"); fflush(stderr);
- return NX_DragOperationNone;
- }
- else
- { // has to be at least "x.rib"
- extension = argv + (strlen(argv) - 4);
- if ((strlen(argv) > 5) && (!strcmp(extension, ".rib")))
- { if (theEvent->flags & NX_ALTERNATEMASK)
- { return NX_DragOperationCopy;
- }
- else
- { return NX_DragOperationGeneric;
- }
- }
-
- // maybe it's a "xxxx.eve" file...
- if ((strlen(argv) > 5) && (!strcmp(extension, ".eve")))
- { if (theEvent->flags & NX_ALTERNATEMASK)
- { return NX_DragOperationCopy;
- }
- else
- { return NX_DragOperationGeneric;
- }
- }
- // maybe it's a "xxxx.mdl" file...
- if ((strlen(argv) > 5) && (!strcmp(extension, ".mdl")))
- { if (theEvent->flags & NX_ALTERNATEMASK)
- { return NX_DragOperationCopy;
- }
- else
- { return NX_DragOperationGeneric;
- }
- }
-
- // maybe it's a "xxxx.scn" file...
- if ((strlen(argv) > 5) && (!strcmp(extension, ".scn")))
- { return NX_DragOperationGeneric;
- }
-
- // maybe it's an .slo file...
- if ((strlen(argv) > 5) && (!strcmp(extension, ".slo")))
- { return NX_DragOperationCopy;
- }
-
- // maybe it's a .wwcam or .cam file
- if ((strlen(argv) > 5) && (!strcmp(extension, ".cam")))
- { return NX_DragOperationCopy;
- }
-
- // maybe it's a .cam.nib
- extension = argv + (strlen(argv) - 8);
- if ((strlen(argv) > 9) && (!strcmp(extension, ".cam.nib")))
- { // we should set this shader as the shader for the currently selected shape
- return NX_DragOperationCopy;
- }
-
- // maybe it's a "xxxx.wwModel" file...
- extension = argv + (strlen(argv) - 8);
- if ((strlen(argv) > 9) && (!strcmp(extension, ".wwModel")))
- { if (theEvent->flags & NX_ALTERNATEMASK)
- { return NX_DragOperationCopy;
- }
- else
- { return NX_DragOperationGeneric;
- }
- }
- // maybe it's a "xxxx.wwScene" file...
- extension = argv + (strlen(argv) - 8);
- if ((strlen(argv) > 9) && (!strcmp(extension, ".wwScene")))
- { if (theEvent->flags & NX_ALTERNATEMASK)
- { return NX_DragOperationCopy;
- }
- else
- { return NX_DragOperationGeneric;
- }
- }
-
- // maybe it's an archived version of a WW3DShader object...
- extension = argv + (strlen(argv) - 11);
- if ((strlen(argv) > 12) && (!strcmp(extension, ".WW3DShader")))
- { // we should set this shader as the shader for the currently selected shape
- fprintf(stderr, "should be setting current shape's shader to this unarchived one...\n");
- return NX_DragOperationNone;
- }
-
- // maybe it's a model template file...
- extension = argv + (strlen(argv) - 12);
- if ((strlen(argv) > 13) && (!strcmp(extension, ".mdlTemplate")))
- { return NX_DragOperationCopy;
- }
-
- // maybe it's a .nib file...
- extension = argv + (strlen(argv) - 4);
- if ((strlen(argv) > 5) && (!strcmp(extension, ".nib")))
- { // really should have some way of dropping it so the camera's interp
- // gets it, but I guess that's what a .cam.nib is...
- return NX_DragOperationCopy;
- }
- }
- }
- return NX_DragOperationNone;
- }
-
-
-
- - (NXDragOperation)draggingUpdated:(id <NXDraggingInfo>)sender
- {
- Pasteboard *pboard;
- char *argv;
- int len;
- const NXAtom *theType;
- char *extension;
- NXEvent *theEvent = [NXApp currentEvent];
-
-
- pboard = [sender draggingPasteboard];
- theType = [pboard types];
-
- if (*theType != NXFilenamePboardType)
- { if ([pboard readType:NXFilenamePboardType data:&argv length:&len] == nil)
- { fprintf(stderr, "unable to read filename from pasteboard.\n"); fflush(stderr);
- return NX_DragOperationNone;
- }
- else
- { // has to be at least "x.rib"
- extension = argv + (strlen(argv) - 4);
- if ((strlen(argv) > 5) && (!strcmp(extension, ".rib")))
- { if (theEvent->flags & NX_ALTERNATEMASK)
- { return NX_DragOperationCopy;
- }
- else
- { return NX_DragOperationGeneric;
- }
- }
-
- // maybe it's a "xxxx.eve" file...
- if ((strlen(argv) > 5) && (!strcmp(extension, ".eve")))
- { if (theEvent->flags & NX_ALTERNATEMASK)
- { return NX_DragOperationCopy;
- }
- else
- { return NX_DragOperationGeneric;
- }
- }
- // maybe it's a "xxxx.mdl" file...
- if ((strlen(argv) > 5) && (!strcmp(extension, ".mdl")))
- { if (theEvent->flags & NX_ALTERNATEMASK)
- { return NX_DragOperationCopy;
- }
- else
- { return NX_DragOperationGeneric;
- }
- }
-
- // maybe it's a "xxxx.scn" file...
- if ((strlen(argv) > 5) && (!strcmp(extension, ".scn")))
- { return NX_DragOperationGeneric;
- }
-
- // maybe it's an .slo file...
- if ((strlen(argv) > 5) && (!strcmp(extension, ".slo")))
- { return NX_DragOperationCopy;
- }
-
- // maybe it's a .wwcam or .cam file
- if ((strlen(argv) > 5) && (!strcmp(extension, ".cam")))
- { return NX_DragOperationCopy;
- }
-
- // maybe it's a .cam.nib
- extension = argv + (strlen(argv) - 8);
- if ((strlen(argv) > 9) && (!strcmp(extension, ".cam.nib")))
- { // we should set this shader as the shader for the currently selected shape
- return NX_DragOperationCopy;
- }
-
- // maybe it's a "xxxx.wwModel" file...
- extension = argv + (strlen(argv) - 8);
- if ((strlen(argv) > 9) && (!strcmp(extension, ".wwModel")))
- { if (theEvent->flags & NX_ALTERNATEMASK)
- { return NX_DragOperationCopy;
- }
- else
- { return NX_DragOperationGeneric;
- }
- }
- // maybe it's a "xxxx.wwScene" file...
- extension = argv + (strlen(argv) - 8);
- if ((strlen(argv) > 9) && (!strcmp(extension, ".wwScene")))
- { if (theEvent->flags & NX_ALTERNATEMASK)
- { return NX_DragOperationCopy;
- }
- else
- { return NX_DragOperationGeneric;
- }
- }
-
- // maybe it's an archived version of a WW3DShader object...
- extension = argv + (strlen(argv) - 11);
- if ((strlen(argv) > 12) && (!strcmp(extension, ".WW3DShader")))
- { // we should set this shader as the shader for the currently selected shape
- fprintf(stderr, "should be setting current shape's shader to this unarchived one...\n");
- return NX_DragOperationNone;
- }
-
- // maybe it's a model template file...
- extension = argv + (strlen(argv) - 12);
- if ((strlen(argv) > 13) && (!strcmp(extension, ".mdlTemplate")))
- { return NX_DragOperationCopy;
- }
-
- // maybe it's a .nib file...
- extension = argv + (strlen(argv) - 4);
- if ((strlen(argv) > 5) && (!strcmp(extension, ".nib")))
- { // really should have some way of dropping it so the camera's interp
- // gets it, but I guess that's what a .cam.nib is...
- return NX_DragOperationCopy;
- }
- }
- }
- return NX_DragOperationNone;
- }
-
-
- - (BOOL)performDragOperation:(id <NXDraggingInfo>)sender { return YES; }
-
- // do the real work here, as it might be awhile...
- - concludeDragOperation:(id <NXDraggingInfo>)sender
- {
- Pasteboard *pboard;
- char *argv;
- int len, ret;
- const NXAtom *theType;
- char *extension;
- id newShader;
- static char shaderName[256];
- static char cmdBuf[MAXPATHLEN + 32];
- NXEvent *theEvent = [NXApp currentEvent];
-
-
- pboard = [sender draggingPasteboard];
- theType = [pboard types];
-
- if (*theType != NXFilenamePboardType)
- { if ([pboard readType:NXFilenamePboardType data:&argv length:&len] == nil)
- { fprintf(stderr, "unable to read filename from pasteboard.\n"); fflush(stderr);
- return nil;
- }
- else
- { // has to be at least "x.rib"
- extension = argv + (strlen(argv) - 4);
- if ((strlen(argv) > 5) && (!strcmp(extension, ".rib")))
- { if (theEvent->flags & NX_ALTERNATEMASK)
- { if (![self addToShapeHierarchyFromRIBFile:argv])
- { return nil;
- }
- return self;
- }
- else
- { if (![self buildNewShapeHierarchyFromRIBFile:argv])
- { return nil;
- }
- return self;
- }
- }
-
- // maybe it's a "xxxx.eve" file...
- if ((strlen(argv) > 5) && (!strcmp(extension, ".eve")))
- { if (theEvent->flags & NX_ALTERNATEMASK)
- { if (![self addToShapeHierarchyFromEveFile:argv])
- { return nil;
- }
- return self;
- }
- else
- { if (![self buildNewShapeHierarchyFromEveFile:argv])
- { return nil;
- }
- return self;
- }
- }
- // maybe it's a "xxxx.mdl" file...
- if ((strlen(argv) > 5) && (!strcmp(extension, ".mdl")))
- { if (theEvent->flags & NX_ALTERNATEMASK)
- { if (![self addToShapeHierarchyFromMdlFile:argv])
- { return nil;
- }
- return self;
- }
- else
- { if (![self buildNewShapeHierarchyFromMdlFile:argv])
- { return nil;
- }
- return self;
- }
- }
-
- // maybe it's a "xxxx.scn" file...
- if ((strlen(argv) > 5) && (!strcmp(extension, ".scn")))
- { if (![self buildNewShapeHierarchyFromSceneFile:argv])
- { return nil;
- }
- return self;
- }
-
- // maybe it's an .slo file...
- if ((strlen(argv) > 5) && (!strcmp(extension, ".slo")))
- { // we should set this shader as the shader for the currently selected shape
- fprintf(stderr, "setting current shape's shader...\n");
- basename(argv, ".slo", shaderName);
- newShader = [(WW3DShader *)[[WW3DShader alloc] init] setShader:shaderName];
- if (!newShader)
- { return nil;
- }
- [[camera currentShape] setShader_:newShader];
- return self;
- }
-
- // maybe it's a .wwcam or .cam file
- if ((strlen(argv) > 5) && (!strcmp(extension, ".cam")))
- { // we should set this shader as the shader for the currently selected shape
- sprintf(cmdBuf, "source %s", argv);
- ret = [[camera tclInterp] eval:cmdBuf];
- if (ret != TCL_OK)
- { char *errorInfo = Tcl_GetVar([[camera tclInterp] interp], "errorInfo", 0);
- NXLogError("problem sourcing file:\n%s", errorInfo);
- return nil;
- }
- return self;
- }
-
- // maybe it's a .cam.nib
- extension = argv + (strlen(argv) - 8);
- if ((strlen(argv) > 9) && (!strcmp(extension, ".cam.nib")))
- { // we should set this shader as the shader for the currently selected shape
- [[camera tclInterp] loadControlPanel:argv modally:NO];
- return self;
- }
-
- // maybe it's a "xxxx.wwModel" file...
- extension = argv + (strlen(argv) - 8);
- if ((strlen(argv) > 9) && (!strcmp(extension, ".wwModel")))
- { if (theEvent->flags & NX_ALTERNATEMASK)
- { if (![self addToShapeHierarchyFromMdlFile:argv])
- { return nil;
- }
- return self;
- }
- else
- { if (![self buildNewShapeHierarchyFromMdlFile:argv])
- { return nil;
- }
- return self;
- }
- }
- // maybe it's a "xxxx.wwScene" file...
- extension = argv + (strlen(argv) - 8);
- if ((strlen(argv) > 9) && (!strcmp(extension, ".wwScene")))
- { if (theEvent->flags & NX_ALTERNATEMASK)
- { if (![self addToShapeHierarchyFromSceneFile:argv])
- { return nil;
- }
- return self;
- }
- else
- { if (![self buildNewShapeHierarchyFromSceneFile:argv])
- { return nil;
- }
- return self;
- }
- }
-
- // maybe it's an archived version of a WW3DShader object...
- extension = argv + (strlen(argv) - 11);
- if ((strlen(argv) > 12) && (!strcmp(extension, ".WW3DShader")))
- { // we should set this shader as the shader for the currently selected shape
- fprintf(stderr, "should be setting current shape's shader to this unarchived one...\n");
- return self;
- }
-
- // maybe it's a model template file...
- extension = argv + (strlen(argv) - 12);
- if ((strlen(argv) > 13) && (!strcmp(extension, ".mdlTemplate")))
- { if (![self readMdlTemplateFile:argv])
- { return nil;
- }
- return self;
- }
-
- // maybe it's a .nib file...
- extension = argv + (strlen(argv) - 4);
- if ((strlen(argv) > 5) && (!strcmp(extension, ".nib")))
- { // really should have some way of dropping it so the camera's interp
- // gets it, but I guess that's what a .cam.nib is...
- [[ribParser tclInterp] loadControlPanel:argv modally:NO];
- return self;
- }
- }
- }
- return nil;
- }
-
- - takeTreatAttributeBeginLikeStartShape:sender
- { [ribParser takeTreatAttributeBeginLikeStartShape:sender];
- return self;
- }
-
- - takeTreatTransformBeginLikeAttributeBegin:sender
- { [ribParser takeTreatTransformBeginLikeAttributeBegin:sender];
- return self;
- }
-
- - takeApplyShadersDirectlyToCurrentShape:sender
- { [ribParser takeApplyShadersDirectlyToCurrentShape:sender];
- return self;
- }
-
- - takeAmbientLightState:sender
- { [camera takeAmbientLightState:sender];
- [delegate sceneWasUpdated:camera];
- return [self revertControlPanel];
- }
- - takeAmbientLightIntensity:sender
- { [camera takeAmbientLightIntensity:sender];
- [delegate sceneWasUpdated:camera];
- return [self revertControlPanel];
- }
- - takeAmbientLightColor:sender
- { [camera takeAmbientLightColor:sender];
- [delegate sceneWasUpdated:camera];
- return [self revertControlPanel];
- }
- - takeLeftLightState:sender
- { [camera takeLeftLightState:sender];
- [delegate sceneWasUpdated:camera];
- return [self revertControlPanel];
- }
- - takeLeftLightIntensity:sender
- { [camera takeLeftLightIntensity:sender];
- [delegate sceneWasUpdated:camera];
- return [self revertControlPanel];
- }
- - takeLeftLightColor:sender
- { [camera takeLeftLightColor:sender];
- [delegate sceneWasUpdated:camera];
- return [self revertControlPanel];
- }
- - takeRightLightState:sender
- { [camera takeRightLightState:sender];
- [delegate sceneWasUpdated:camera];
- return [self revertControlPanel];
- }
- - takeRightLightIntensity:sender
- { [camera takeRightLightIntensity:sender];
- [delegate sceneWasUpdated:camera];
- return [self revertControlPanel];
- }
- - takeRightLightColor:sender
- { [camera takeRightLightColor:sender];
- [delegate sceneWasUpdated:camera];
- return [self revertControlPanel];
- }
-
- - takeRenderWorldAsBox:sender
- { [camera takeRenderWorldAsBox:sender];
- [delegate sceneWasUpdated:camera];
- return [self revertControlPanel];
- }
- - takeRenderCurrentAsBox:sender
- { [camera takeRenderCurrentAsBox:sender];
- [delegate sceneWasUpdated:camera];
- return [self revertControlPanel];
- }
- - takeWorldIsVisible:sender
- { [camera takeWorldIsVisible:sender];
- [delegate sceneWasUpdated:camera];
- return [self revertControlPanel];
- }
- - takeCurrentIsVisible:sender
- { [camera takeCurrentIsVisible:sender];
- [delegate sceneWasUpdated:camera];
- return [self revertControlPanel];
- }
-
- - (BOOL)treatTransformBeginLikeAttributeBegin { return [ribParser treatTransformBeginLikeAttributeBegin]; }
-
- - (BOOL)renderWorldAsBox { return [camera renderWorldAsBox]; }
- - (BOOL)renderCurrentAsBox { return [camera renderCurrentAsBox]; }
- - (BOOL)worldIsVisible { return [camera worldIsVisible]; }
- - (BOOL)currentIsVisible { return [camera currentIsVisible]; }
-
- - (BOOL)ambientLightState { return [camera ambientLightState]; }
- - (RtFloat)ambientLightIntensity { return [camera ambientLightIntensity]; }
- - (NXColor)ambientLightColor { return [camera ambientLightColor]; }
- - (BOOL)leftLightState { return [camera leftLightState]; }
- - (RtFloat)leftLightIntensity { return [camera leftLightIntensity]; }
- - (NXColor)leftLightColor { return [camera leftLightColor]; }
- - (BOOL)rightLightState { return [camera rightLightState]; }
- - (RtFloat)rightLightIntensity { return [camera rightLightIntensity]; }
- - (NXColor)rightLightColor { return [camera rightLightColor]; }
-
- - sendStringToCamera:sender
- {
- int ret;
- char *retString;
- id tclInterp = [camera tclInterp];
- BOOL oldFlag = [tclInterp showErrors];
-
-
- if (cameraHistoryText)
- { [cameraHistoryText setSel:[cameraHistoryText textLength] :[cameraHistoryText textLength]];
- [cameraHistoryText setSelGray:NX_BLACK];
- [cameraHistoryText replaceSel:"--> "];
- [cameraHistoryText setSelColor:sendTextColor];
- [cameraHistoryText replaceSel:[sender stringValue]];
- [cameraHistoryText replaceSel:"\n"];
- [cameraHistoryText scrollSelToVisible];
- }
- if ([sender respondsTo:@selector(selectedCell)])
- { sender = [sender selectedCell];
- }
-
- // the the tcl interp we want to handle our own errors
- [tclInterp setShowErrors:NO];
- retString = [tclInterp eval:[sender stringValue] :&ret];
- [tclInterp setShowErrors:oldFlag];
- if (cameraHistoryText)
- { if (ret)
- { [cameraHistoryText setSelGray:NX_BLACK];
- [cameraHistoryText replaceSel:"ERROR: "];
- [cameraHistoryText replaceSel:retString];
- [cameraHistoryText replaceSel:"\n"];
- [cameraHistoryText scrollSelToVisible];
- }
- else
- { [cameraHistoryText setSelGray:NX_BLACK];
- [cameraHistoryText replaceSel:"<-- "];
- [cameraHistoryText setSelColor:replyTextColor];
- [cameraHistoryText replaceSel:retString];
- [cameraHistoryText replaceSel:"\n"];
- [cameraHistoryText scrollSelToVisible];
- }
- }
- if (retString) { free(retString); }
- [cameraInterpTextField selectText:nil];
-
- return self;
- }
-
-
- - sendStringToShapes:sender
- {
- int ret;
- char *retString;
- id tclInterp = [ribParser tclInterp];
- BOOL oldFlag = [tclInterp showErrors];
-
-
- if (shapeHistoryText)
- { [shapeHistoryText setSel:[shapeHistoryText textLength] :[shapeHistoryText textLength]];
- [shapeHistoryText setSelGray:NX_BLACK];
- [shapeHistoryText replaceSel:"--> "];
- [shapeHistoryText setSelColor:sendTextColor];
- [shapeHistoryText replaceSel:[sender stringValue]];
- [shapeHistoryText replaceSel:"\n"];
- [shapeHistoryText scrollSelToVisible];
- }
- if ([sender respondsTo:@selector(selectedCell)])
- { sender = [sender selectedCell];
- }
-
- // the the tcl interp we want to handle our own errors
- [tclInterp setShowErrors:NO];
- retString = [tclInterp eval:[sender stringValue] :&ret];
- [tclInterp setShowErrors:oldFlag];
- if (shapeHistoryText)
- { if (ret)
- { [shapeHistoryText setSelGray:NX_BLACK];
- [shapeHistoryText replaceSel:"ERROR: "];
- [shapeHistoryText replaceSel:retString];
- [shapeHistoryText replaceSel:"\n"];
- [shapeHistoryText scrollSelToVisible];
- }
- else
- { [shapeHistoryText setSelGray:NX_BLACK];
- [shapeHistoryText replaceSel:"<-- "];
- [shapeHistoryText setSelColor:replyTextColor];
- [shapeHistoryText replaceSel:retString];
- [shapeHistoryText replaceSel:"\n"];
- [shapeHistoryText scrollSelToVisible];
- }
- }
- [shapeInterpTextField selectText:nil];
-
- return self;
- }
-
-
- - updateCameraInspector:sender { [self revertCameraInspector]; return self; }
-
-
- // this is kind of a hack, but necessary...
- - synchCameraToSceneClock
- {
- [camera synchToSceneClock:sceneClock];
-
- return self;
- }
-
-
-
- /// new camera stuff
- - takeFocalLength:sender { [camera takeFocalLength:sender]; return [self revertCameraInspector]; }
- - takeFocalDistance:sender { [camera takeFocalDistance:sender]; return [self revertCameraInspector]; }
- - takeFStop:sender { [camera takeFStop:sender]; return [self revertCameraInspector]; }
- - takeExposureLength:sender { [camera takeExposureLength:sender]; return [self revertCameraInspector]; }
-
- - takeShotOutputTypeFromMatrix:sender { [camera takeShotOutputTypeFromMatrix:sender]; return [self revertCameraInspector]; }
-
- - takeShotLength:sender { [camera takeShotLength:sender]; return [self revertCameraInspector];}
- - takeFramesPerSecond:sender; { [camera takeFramesPerSecond:sender]; return [self revertCameraInspector]; }
- - takeFrameNumber:sender { [camera takeFrameNumber:sender]; return [self revertCameraInspector]; }
-
- - takeExposureLengthFactor:sender { [camera takeExposureLengthFactor:sender]; return [self revertCameraInspector]; }
- - takeExposureLengthPercentage:sender { [camera setExposureLengthFactor:([sender floatValue] / 100.)]; return [self revertCameraInspector]; }
- - takeShotStartTime:sender { [camera takeShotStartTime:sender]; return [self revertCameraInspector]; }
- - takeExposureLengthAsStrobe:sender { [camera setExposureLengthFactor:0.0]; return [self revertCameraInspector]; }
- - takeExposureLengthAsFilm:sender { [camera setExposureLengthFactor:0.5]; return [self revertCameraInspector]; }
- - takeExposureLengthAsVideo:sender { [camera setExposureLengthFactor:1.0]; return [self revertCameraInspector]; }
-
- // even newer camera stuff
- - takeEyePoint:sender
- {
- RtPoint anEyePoint, aViewPoint;
- float aRollAngle;
-
-
- // need to make sure that the sender is a Matrix:
- if ([sender isKindOf:[Matrix class]])
- { [camera getEyeAt:&anEyePoint toward:&aViewPoint roll:&aRollAngle];
- N3D_XComp(anEyePoint) = [[sender cellAt:0 :0] floatValue];
- N3D_YComp(anEyePoint) = [[sender cellAt:0 :1] floatValue];
- N3D_ZComp(anEyePoint) = [[sender cellAt:0 :2] floatValue];
- [camera setEyeAt:anEyePoint toward:aViewPoint roll:aRollAngle];
- [self revertCameraInspector];
- [camera display];
- }
- else
- { NXLogError("should only send a takeEyePoint: msg from a subclass of Matrix (which %s isn't)", [[sender class] name]);
- }
-
- return self;
- }
-
-
- - takeLookAt:sender
- {
- RtPoint anEyePoint, aViewPoint;
- float aRollAngle;
-
-
- // need to make sure that the sender is a Matrix:
- if ([sender isKindOf:[Matrix class]])
- { [camera getEyeAt:&anEyePoint toward:&aViewPoint roll:&aRollAngle];
- N3D_XComp(aViewPoint) = [[sender cellAt:0 :0] floatValue];
- N3D_YComp(aViewPoint) = [[sender cellAt:0 :1] floatValue];
- N3D_ZComp(aViewPoint) = [[sender cellAt:0 :2] floatValue];
- [camera setEyeAt:anEyePoint toward:aViewPoint roll:aRollAngle];
- [self revertCameraInspector];
- [camera display];
- }
- else
- { NXLogError("should only send a takeLookAt: msg from a subclass of Matrix (which %s isn't)", [[sender class] name]);
- }
-
- return self;
- }
-
-
- - takeRollAngle:sender
- {
- RtPoint anEyePoint, aViewPoint;
- float aRollAngle;
-
-
- [camera getEyeAt:&anEyePoint toward:&aViewPoint roll:&aRollAngle];
- aRollAngle = [sender floatValue];
- [camera setEyeAt:anEyePoint toward:aViewPoint roll:aRollAngle];
- [self revertCameraInspector];
- [camera display];
-
- return self;
- }
-
- - setCurrentShapeTransformMatrixToIdentity:sender
- {
- [[camera currentShape] setTransformMatrix:(RtFloat (*)[4])N3DIdentityMatrix];
- [self revertControlPanel];
- [camera display];
- return self;
- }
-
- - takeCurrentShapeTransformMatrix:sender
- {
- RtMatrix aMatrix;
-
-
- if ([sender isKindOf:[Matrix class]])
- { aMatrix[0][0] = [[sender cellAt:0 :0] floatValue];
- aMatrix[0][1] = [[sender cellAt:0 :1] floatValue];
- aMatrix[0][2] = [[sender cellAt:0 :2] floatValue];
- aMatrix[0][3] = [[sender cellAt:0 :3] floatValue];
-
- aMatrix[1][0] = [[sender cellAt:1 :0] floatValue];
- aMatrix[1][1] = [[sender cellAt:1 :1] floatValue];
- aMatrix[1][2] = [[sender cellAt:1 :2] floatValue];
- aMatrix[1][3] = [[sender cellAt:1 :3] floatValue];
-
- aMatrix[2][0] = [[sender cellAt:2 :0] floatValue];
- aMatrix[2][1] = [[sender cellAt:2 :1] floatValue];
- aMatrix[2][2] = [[sender cellAt:2 :2] floatValue];
- aMatrix[2][3] = [[sender cellAt:2 :3] floatValue];
-
- aMatrix[3][0] = [[sender cellAt:3 :0] floatValue];
- aMatrix[3][1] = [[sender cellAt:3 :1] floatValue];
- aMatrix[3][2] = [[sender cellAt:3 :2] floatValue];
- aMatrix[3][3] = [[sender cellAt:3 :3] floatValue];
-
- [[camera currentShape] setTransformMatrix:aMatrix];
- [self revertControlPanel];
- [camera display];
- }
- else
- { NXLogError("should only send a takeCurrentShapeTransformMatrix: msg from a subclass of Matrix (which %s isn't)", [[sender class] name]);
- }
-
- return self;
- }
-
- - setCameraPreTransformMatrixToIdentity:sender
- {
- [camera setPreTransformMatrix:(RtFloat (*)[4])N3DIdentityMatrix];
- [self revertCameraInspector];
- [camera display];
- return self;
- }
-
- - takeCameraPreTransformMatrix:sender
- {
- RtMatrix aMatrix;
-
-
- if ([sender isKindOf:[Matrix class]])
- { aMatrix[0][0] = [[sender cellAt:0 :0] floatValue];
- aMatrix[0][1] = [[sender cellAt:0 :1] floatValue];
- aMatrix[0][2] = [[sender cellAt:0 :2] floatValue];
- aMatrix[0][3] = [[sender cellAt:0 :3] floatValue];
-
- aMatrix[1][0] = [[sender cellAt:1 :0] floatValue];
- aMatrix[1][1] = [[sender cellAt:1 :1] floatValue];
- aMatrix[1][2] = [[sender cellAt:1 :2] floatValue];
- aMatrix[1][3] = [[sender cellAt:1 :3] floatValue];
-
- aMatrix[2][0] = [[sender cellAt:2 :0] floatValue];
- aMatrix[2][1] = [[sender cellAt:2 :1] floatValue];
- aMatrix[2][2] = [[sender cellAt:2 :2] floatValue];
- aMatrix[2][3] = [[sender cellAt:2 :3] floatValue];
-
- aMatrix[3][0] = [[sender cellAt:3 :0] floatValue];
- aMatrix[3][1] = [[sender cellAt:3 :1] floatValue];
- aMatrix[3][2] = [[sender cellAt:3 :2] floatValue];
- aMatrix[3][3] = [[sender cellAt:3 :3] floatValue];
-
- [camera setPreTransformMatrix:aMatrix];
- [self revertCameraInspector];
- [camera display];
- }
- else
- { NXLogError("should only send a takeCameraPreTransformMatrix: msg from a subclass of Matrix (which %s isn't)", [[sender class] name]);
- }
-
- return self;
- }
-
- // delegate methods
-
- // this is sent whenever the contents of the well is changed
- - wellWasUpdated:camera { [self display]; return self; }
-
- // this method is sent whenever the scene changes in such a way that
- // if the user rerendered the scene photorealistically, they would notice
- // a difference.
- - sceneWasUpdated:camera { return self; }
-
- // this method is sent whenever the underlying controls on the scene were
- // changed such that if the user manipulated the scene, it would react
- // differently
- - cameraParametersWereUpdated:camera { [self invalidateCameraInspector]; return self; }
- - controlsWereUpdated:camera { [self revertControlPanel]; return self; }
-
-
- //---------------------------------------------------------------------------------------------------------
- // IB Methods
- //---------------------------------------------------------------------------------------------------------
-
- - (const char *)getInspectorClassName { return "WW3DWellIBInspector"; }
-
-
- //---------------------------------------------------------------------------------------------------------
- // archiving Methods
- //---------------------------------------------------------------------------------------------------------
-
- #define typeVectorVersion1 "{ffff}{ffff}@if"
- #define typeValuesVersion1 &bezelRect, &wellRect, &camera, &aspectRatioType, &aspectRatio
-
- #define typeVectorVersion2 "{ffff}{ffff}@ifc"
- #define typeValuesVersion2 &bezelRect, &wellRect, &camera, &aspectRatioType, &aspectRatio, &reuseImageView
-
- #define typeVectorVersion3 "{ffff}{ffff}@ifc@"
- #define typeValuesVersion3 &bezelRect, &wellRect, &camera, &aspectRatioType, &aspectRatio, &reuseImageView, &sceneClock
-
- #define typeVector "@ifc@"
- #define typeValues &camera, &aspectRatioType, &aspectRatio, &reuseImageView, &sceneClock
-
- - read:(NXTypedStream*)stream
- {
- int version;
-
- [super read:stream];
-
- NX_DURING
- version = NXTypedStreamClassVersion(stream, "WW3DWell");
- if (version == 0) NXReadTypes(stream,"i",&version), version=1;
- if (version == 1) {
- NXReadTypes(stream, typeVectorVersion1, typeValuesVersion1);
- imageView = NXReadObject(stream);
- reuseImageView = YES;
- sceneClock = [[WWSceneClock alloc] init];
- useRendribInstead = NO;
- beepWhenDone = YES;
- }
- if (version == 2) {
- NXReadTypes(stream, typeVectorVersion2, typeValuesVersion2);
- imageView = NXReadObject(stream);
- sceneClock = [[WWSceneClock alloc] init];
- useRendribInstead = NO;
- beepWhenDone = YES;
- }
- if (version == 3) {
- NXReadTypes(stream, typeVectorVersion3, typeValuesVersion3);
- imageView = NXReadObject(stream);
- useRendribInstead = NO;
- beepWhenDone = YES;
- }
- if (version == 4) {
- NXReadTypes(stream, typeVector, typeValues);
- NXReadRect(stream, &bezelRect);
- NXReadRect(stream, &wellRect);
- imageView = NXReadObject(stream);
- useRendribInstead = NO;
- beepWhenDone = YES;
- }
- if (version == 5) {
- NXReadTypes(stream, typeVector, typeValues);
- NXReadRect(stream, &bezelRect);
- NXReadRect(stream, &wellRect);
- imageView = NXReadObject(stream);
- NXReadTypes(stream, "cc", &useRendribInstead, &beepWhenDone);
- }
- NX_HANDLER
- NXLogError("in read: %s, exception [%d] raised.\n", [[self class] name], NXLocalHandler.code);
- return nil;
- NX_ENDHANDLER
-
- return self;
- }
-
- - write:(NXTypedStream*)stream
- {
- [super write:stream];
- NXWriteTypes(stream, typeVector, typeValues);
- NXWriteRect(stream, &bezelRect);
- NXWriteRect(stream, &wellRect);
- NXWriteObjectReference(stream, imageView);
- NXWriteTypes(stream, "cc", &useRendribInstead, &beepWhenDone);
- return self;
- }
-
-
- @end
-